最近看mybatis的时候做了一个练习,但是进行事务处理的时候出了问题,如下

package com.henu.lz.controller;  

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import com.henu.lz.dao.PersonMapper;
import com.henu.lz.model.Person; @Controller
public class SupplierController { @Autowired
PersonMapper personMapper; @Transactional
@RequestMapping("/add")
public String addPerson(
@RequestParam("name1") String name1,
@RequestParam("age1") int age1,
@RequestParam("name2") String name2,
@RequestParam("age2") int age2,
Model model) { Person person1 = new Person();
Person person2 = new Person();
person1.setName(name1);
person1.setAge(age1);
person2.setName(name2);
person2.setAge(age2); personMapper.save(person1);
personMapper.save(person2); model.addAttribute("message", "添加成功!");
return "success";
}
}

spring容器和springmvc的配置都没有问题,dao层就是mybatis比较与众不同的的写有sql的xml以及接口。在从前台传值的时候person1正常传,person2传能抛SQLException的值,按理说事务应该回滚的,数据库中不会有person1,但是查看数据库却有person1。用的mysql,引擎设置为innodb后还是这样,换了oracle之后依然如此。这两次save不在一个事务。

网上看了下别人的经历,有的是try…catch之后自行处理没有throw,有的是说设置rollbackFor……有一个比较接近

http://www.iteye.com/topic/714686

用的是 hibernate 3.2,在配置dao和controller的时候都用了注解方式自动扫描

<context:component-scan base-package="com..." />  

这样说是导致dao中事务无效,我试过这样配置,服务启动直接就出错了,很显然冲突,而且用context:include-filter和context:exclude-filter来屏蔽掉controller层的解决办法也有点没必要,分别扫描dao层和controller层不就行了,我是这样配置的。

查看mybatis官网上的project,是比我多了一层service层,然后在service中用的@transactional,我加了一层

package com.henu.lz.service;  

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import com.henu.lz.dao.PersonMapper;
import com.henu.lz.model.Person; @Service(value="personService")
public class PersonServiceImpl implements PersonService { @Autowired
private PersonMapper personMapper; @Transactional
public void save(Person p1, Person p2) {
personMapper.save(p1);
personMapper.save(p2);
} }

相应的,controller也修改为

package com.henu.lz.controller;  

import javax.annotation.Resource;  

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.henu.lz.model.Person;
import com.henu.lz.service.PersonService; @Controller
public class SupplierController { @Resource
private PersonService personService; @RequestMapping("/add")
public String addPerson(
@RequestParam("name1") String name1,
@RequestParam("age1") int age1,
@RequestParam("name2") String name2,
@RequestParam("age2") int age2,
Model model) { Person person1 = new Person();
Person person2 = new Person();
person1.setName(name1);
person1.setAge(age1);
person2.setName(name2);
person2.setAge(age2); personService.save(person1, person2); model.addAttribute("message", "添加成功!");
return "success";
}
}

这时再按开始那样传值能得到预期结果了。

一开始也注意到少了一层service,但是觉得在controller中做同样的事情也可以的,所以就杯具了。

因为spring的context和mvc是分开的,貌似controller不能被注册到spring的context中,于是不能被transactionManager拦截,那么controller中那个@transactional就不起作用了。看了声明式事务的五种配置,都是对注册到context中的bean起作用的,不论是拦截器方式还是aop:config方式。

事务注解方式不能应用于接口,我的mapper用的又是xml方式的,所以只能加一层service,然后controller中的交易就放在service层。

springmvc的controller中使用@Transactional无效的更多相关文章

  1. spring aop在mvc的controller中加入切面无效

    spring aop在mvc的controller中加入切面无效 因为MVC的controller,aop默认使用jdk代理.要使用cglib代理. 在spring-mybatis.xml配置文件中加 ...

  2. SpringMVC的Controller中使用线程安全的初始化

    因为SpringMVC的Controller默认是单例, 在这种情况下, Controller中使用的私有变量必须也是单例, 例如各种service, 否则会有多线程访问数据互相修改的问题. 对于需要 ...

  3. springmvc 解决 controller 中出现死循环并 stackoverflow 的问题

    这是因为这个controller中的方法返回值为void类型,且没有request response这类衍生的重定向,或者返回值为String,但是是null等等的情况,都会引起死循环,然后stack ...

  4. 在springMVC的controller中获取request,response对象的一个方法

    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttr ...

  5. springMVC:将controller中数据传递到jsp页面

    1> 将方法的返回值该为ModelAndView在返回时,将数据存储在ModelAndView对象中如: newModelAndView("/WEBINF/jsp/showData.j ...

  6. springboot项目中,@transactional 无效

    问题: springboot项目,依然是使用jpa.Hibernate来操作mysql,涉及到数据库的操作,就少不了事务.写了一个接口,用来测试@Transaction注解的作用,发现没有效果 分析: ...

  7. 9.SpringMVC和json结合传递数据 && 10.SpringMVC获取controller中json的数据

  8. SpringMVC Controller中注入Request成员域和在方法中定义中HttpServletRequest有啥区别

    先说结论,在Controller中注入Request是线程安全的. 以下是解释: 我们先来看看这两者有什么不同 在controller注入成员变量request 可以看到注入的是一个代理对象 写在方法 ...

  9. 【转】在SpringMVC Controller中注入Request成员域

    原文链接:https://www.cnblogs.com/abcwt112/p/7777258.html 原文作者:abcwt112 主题 在工作中遇到1个问题....我们定义了一个Controlle ...

随机推荐

  1. 《Linux内核分析》第六周学习小结

    进程的描述和进程的创建 一.进程的描述 进程描述符task_struct数据结构: (1)操作系统的三大功能: 进程管理.内存管理.文件系统 (2)进程的作用: 将信号.进程间通信.内存管理和文件系统 ...

  2. win10装MySQL5.7

    越来越发现装MySQL很费劲啊,装了N次,都很懵逼,找对的解决方案很重要. Mysql5.7下载地址:http://xiazai.zol.com.cn/detail/4/33431.shtml 安装步 ...

  3. 接口(interface)与多态

    1. 接口(interface)是抽象方法与常量值的集合: 2. 从本质上来讲,接口是一种特殊的抽象类,这种抽象类中只包含常量与方法的定义,而没有变量和方法的实现: 3. 接口中声明的属性默认为:pu ...

  4. MySql修改root密码以及允许外网访问

    1.修改root密码 用SET PASSWORD命令 mysql -u root mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('n ...

  5. 文件I/O操作

    熟悉文件的各种流类 了解字符的编码 掌握文件I/O操作的相关概念 了解对象的序列化 简单的引入 I:input  由外围输入到内存 O:output  由内存写出到外存. I/O:是相对于内存来说的 ...

  6. shell脚本--文件查找之find命令

    首先是通过文件名称来查找,需要使用一个-name参数. 查询以  .txt结尾的文件,和以 t 开头的文件: ubuntu@ubuntu:~/test$ ls one.txt three.txt tw ...

  7. shell脚本--文件测试

    文件测试是指测试某一个文件或者目录是否存在 测试文件格式[ 操作符 目录或者文件 ]    注意左括号和操作符之间有一个空格,文件或者目录 与右边的括号之间也有一个空格. -d 测试是否为目录 -e ...

  8. PAT L3-003 社交集群

    https://pintia.cn/problem-sets/994805046380707840/problems/994805053141925888 当你在社交网络平台注册时,一般总是被要求填写 ...

  9. java mail session使用Properties的clone方法

    /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreem ...

  10. 自定义组件的 v-model

    Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Bool ...