@Transactiona注解失效原因
用在非public方法
@Transactional是基于动态代理的,Spring的代理工厂在启动时会扫描所有的类和方法,并检查方法的修饰符是否为public,非public时不会获取@Transactional的属性信息,这时不会生成动态代理对象。
同一个类中,非@Transactional方法调用@Transactional方法
其实是AOP失效原因,类内部方法的调用是通过this调用的,不会使用动态代理对象,事务不会回滚。
异常被"吃了"
Spring是根据抛出的异常来回滚的,如果异常被捕获了没有抛出的话,事务就不会回滚。
(类本身) 未被spring管理
只有被spring扫描到并管理的bean,才支持AOP。
多线程调用
spring的事务是通过数据库连接来实现的。当前线程中保存了一个map,key是数据源,value是数据库连接。只有拥有同一个数据库连接才能同时提交和回滚。如果在不同的线程,拿到的数据库连接肯定是不一样的,所以是不同的事务。
事务管理器设置的不对
TransactionManager配置的DataSource与执行mapper对应Mybatis绑定的DataSource不匹配。
Sping开启事务,将链接与线程绑定,放入TransactionSynchronizationManager,key为数据源,value为链接的包装 TransactionSynchronizationManager.bindResource(this.getDataSource(), txObject.getConnectionHolder()); Mybatis通过配置的数据源获取链接的包装 ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
rollbackFor属性设置不对
Spring默认抛出RuntimeException时才会回滚事务,要想其他类型异常也回滚则需要设置rollbackFor属性的值。
数据库引擎不支持事务
比如使用MyISAM。
浙公网安备 33010602011771号