1.在applicationConext.xml 中配置事务注解驱动mysql
<!-- 事务注解驱动 --> <tx:annotation-driven /> <!-- 配置事务 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="basicDataSource" /> </bean>
2.Service中作以下配置spring
@Service public class AccountService { @Autowired AccountMapper am; @Transactional public void zhuanZhang(Integer fromAcct,Integer toAcct,Double money){ //先减去fromAcct 的钱 am.updateMoneyByAcctNumber(fromAcct, money*(-1)); System.out.println("先减去fromAcct 的钱"+money*(-1)); System.out.println(10/0); //再加上toAcct 上的钱 am.updateMoneyByAcctNumber(toAcct, money); System.out.println("再加上toAcct 上的钱"+money); } }
3.Springmvc.xml 中包扫描的配置以下sql
<!-- 配置包扫描 --> <context:component-scan base-package="cn.zen.controller.*,cn.zen.service" />
4.结果测试事务报错回滚的时候不成功。spring-mvc
查看框架的启动日志看到 Spring没有接管JDBC事务的报错mvc
JDBC Connection [jdbc:mysql://*****, MySQL-AB JDBC Driver] will not be managed by Spring app
5.解决方式是框架
将带有事务注解的包放到ApplicationContext.xml 中扫描,同时在springmvc.xml 中剔除该包的扫描。测试
百度了一下具体缘由,相对明晰的说法:spa
Spring容器优先加载由ServletContextListener,对应applicationContext.xml 产生的父容器,而SpringMVC(对应spring-mvc.xml)产生的是子容器。
子容器Controller进行扫描装配时装配的@Service注解的实例是没有通过事务增强处理,即没有事务处理能力的Service,而父容器进行初始化的Service是保证事务的加强处理能力的。若是不在子容器中将Service exclude掉,此时获得的将是原样的无事务处理能力的Service。 日志
据此获得两个结论:
1.Spring 才能处理事务,Springmvc 不行。2..子容器回覆盖父容器中的相同配置,因此要在包注解扫描的时候在子容器中将Service exclude掉