SSM的配置和@Transactional的使用讲解
SSM也就是常用的Spring + Spring MVC + Mybatis 框架
有时候一个方法涉及到多个表的操作,为了保证安全性,可靠性,得用事务,保证几条sql语句,要么全成功,要么回滚。
本篇博客先讲配置和使用,然后再讲具体的一些原理
一、首先配置事务管理类
在Spring的配置文件—applicant.xml(spring.xml)
1 2 3 4 5 6 | <bean class= "org.springframework.jdbc.datasource.DataSourceTransactionManager" id= "txManager" > <property name = "dataSource" ref= "dataSource" > </property></bean> <! -- 事务控制 --> <tx:annotation-driven transaction -manager= "txManager" > </tx:annotation-driven> |
坑1:MyBatis自动参与到spring事务管理中,无需额外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可,否则事务管理会不起作用。
vc的配置文件">二、修改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的配置文件
1 2 | <context:component-scan base-package= "com.will" > </context:component-scan> |
修改SpringMVC的配置文件
1 2 3 | <context:component-scan base-package= "com.will" > <context:exclude-filter expression= "org.springframework.stereotype.Service" type= "annotation" > </context:exclude-filter></context:component-scan> |
三、@Transactional使用
在Service的某个需要事务回滚的方法上加上@Transactional
1 2 3 4 5 6 7 8 9 10 | //插入 @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”指明本方法使用哪一个事务管理器。
标签:
上一篇: vim 使用大全
下一篇: JAVA 图像处理库 Thumbnails