1、线程中方法,事务会失效
2、线程中方法,事务会失效。即使在线程方法上增加@Transactional注解
3、事务正常回滚,A方法调用B的普通方法
4、事务正常回滚。A方法调用B的private普通方法
6、会抛出NullPointerException异常。
Methods annotated with ‘@Transactional’ must be overridable
用“@Transactional”注释的方法必须是可重写的
private 不能重写,导致事务会失效。
7、事务失效,被cache吃掉了,cache 抛出了exception异常,@Transactional(rollbackFor = RuntimeException.class) 指定回滚RuntimeException
解决:cache改为RuntimeException
8、事务正常回滚。利用代理对象来调用B方法,所以会回滚事务
9、事务失效。普通方法调用,即使B方法添加了@Transactional注解,此时A方法没有事务
总结:
1、mysql默认使用的事务是Innodb存储引擎,它是支持事务的,但是如果你的表的存储引擎是MyISAM,MyISAM是不支持事务的。这样就会出现“事务失效”的问题了。
2、方法内的自调用
Spring事务是基于AOP的,只有使用代理对象调用某个方法的时候,Spring事务才会生效。而在一个方法中调用使用this.xxx()方法的时候,this并不是代理对象,所以事务会失效。
a.自己注入自己
b.AopContext.currentProxy() 一般很少使用
c.把调用方法拆分到另一个bean中
3、方法是private的
如果父类中的某个方法是Private的,那么子类就没有办法重写它,也就无法增加spring事务的逻辑
4、单独的线程调用方法
当mybatis和jdbcTemplate执行sql时,会从ThreadLocal中获取数据连接对象,如果开启事务的线程和执行sql的线程是同一个,那么就能拿到数据库连接对象。如果不是同一个线程,那就拿不到数据库连接对象,这样,mybatis和jdbcTemplate就会自己去创建一个数据库连接来执行sql,此数据库连接的autocommit为true,那么执行完sql就会自动提交,后续再抛出异常就不能再回滚之前已经提交的sql了。
5、异常被吃掉
如果Spring事务没有捕获到异常,自然就不会回滚了。默认情况下Spring会捕获RuntimeRxception和Error。
7、类没有被Spring管理