SSM 配置及使用@Transactional 详解

来源:互联网 发布:开淘宝店怎么样 编辑:程序博客网 时间:2024/06/04 01:09

SSM也就是常用的Spring + Spring MVC + Mybatis 框架
有时候一个方法涉及到多个表的操作,为了保证安全性,可靠性,得用事务,保证几条sql语句,要么全成功,要么回滚。

本篇博客先讲配置和使用,然后再讲具体的一些原理

一、首先配置事务管理类

在Spring的配置文件—applicant.xml(spring.xml)

<bean id="txManager"      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">      <property name="dataSource" ref="dataSource" />  </bean>  <!-- 事务控制   -->  <tx:annotation-driven transaction-manager="txManager" />  

坑1:MyBatis自动参与到spring事务管理中,无需额外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可,否则事务管理会不起作用。

二、修改Spring、SpringMVC的配置文件

坑2:按理说到此应该就可以了,但是Spring+Spring MVC框架会涉及到父子容器。及Spring容器优先加载由ServletContextListener(对应Spring的配置文件,applicationContext.xml)产生的父容器,而SpringMVC(对应Spring MVC的配置文件,mvc_dispatcher_servlet.xml)产生的是子容器。子容器Controller进行扫描装配时装配的@Service注解的实例是没有经过事务加强处理,即没有事务处理能力的Service,而父容器进行初始化的Service是保证事务的增强处理能力的。如果不在子容器中将Service exclude掉,此时得到的将是原样的无事务处理能力的Service,因为在多上下文的情况下,如果同一个bean被定义两次,后面一个优先。

修改Spring的配置文件

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

修改SpringMVC的配置文件

<context:component-scan base-package="com.will" >          <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />    </context:component-scan>  

三、@Transactional使用

在Service的某个需要事务回滚的方法上加上@Transactional

//插入@Transactional(value = "transactionManager02", propagation = Propagation.REQUIRED, rollbackFor={Exception.class}, isolation = Isolation.DEFAULT)    public Integer insertCloudRule(CloudRule rule) {        cloudRuleMapper.insertCloudRule(rule);//        int i = 1/0;        cloudRuleMapper.insertCloudRule(rule);        return 0;    }

坑3:@Transactional 的事务开启 ,或者是基于接口的 或者是基于类的代理被创建。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的。虽然我不理解什么叫基于接口或者类的。。。不过根据最后的结论,大体上推测出为什么@Transactional一般用于Service层

坑4:@Transactional 默认情况下是只回滚未检查异常,也就是sql操作异常并不会回滚,不过按照某人的意思,就应该是这种设计,原话:异常的基本作用是在出问题的时候,能通过日志最快的定位;出现了检查异常不是db操作失败了,而且其他地方;不能用保障db操作的方式来保障其他错误;检查异常是在合理的情况下出现的,就应该把它在程序中处理掉。。。好像挺有道理,但我还是喜欢rollbackFor={Exception.class},只有出错就直接回滚。

坑5:当有多个数据源的时候,就设计到了多个事务管理器,所以最好加上value = “transactionManager02”指明本方法使用哪一个事务管理器。

四、细节及原理等

见下面博客

参考博客:
http://blog.csdn.net/qq_26525215/article/details/77460784

http://baijiahao.baidu.com/s?id=1580660700045482170&wfr=spider&for=pc

http://blog.csdn.net/will_awoke/article/details/12002705

http://www.cnblogs.com/yepei/p/4716112.html