Spring 事务失效的几种场景

警告
本文最后更新于 2021-11-10,文中内容可能已过时。

Spring事务在哪几种情况下会失效?为什么?

spring事务是通过切面实现的,源码在TransactionInterceptor类中。 事务开启依赖数据库链接的,而链接是和线程绑定的。 嵌套事务通过savepoint实现,事务方法中开启新事物则通过获取新的链接进行事务开启(实际就是关闭自动提交)。

链接对象封装在TransactionInfo中,它也记录了前一个事务对象,如果没有则为null。

每开启一个事务,这个事务对象都会绑定到一个ThreadLocal静态变量中,即当前的事务对象。Spring事务切面基于以上逻辑实现了声明式事务管理,及事务属性的传播(在当前存在或不存在事务时,加入当前事务或开启新的事务或以非事务方式执行或在嵌套事务中执行)。

所以在事务方法中

1.使用新的线程执行代码逻辑,会使事务失效。
2.事务方法内部捕获了异常sql的异常,未将抛出到事务切面中,这时候事务会提交,即正常执行的那部分sql执行结果将会生效。
3.未指定回滚的异常,默认是RuntimeException回滚。如果抛出编译期异常,则事务最终也会提交,不会回滚。