spring事务管理

事务的实现方式

编程事务
声明式事务,目前最常用的就是@Transactional

spring事务传播行为

Spring事务管理:是对数据库事务的抽象封装,通过AOP(面向切面编程)实现,旨在简化传统JDBC手动事务管理的复杂性
事务传播:一个线程运行时可能接连调用好几个方法,在调用某一个方法时可能就开启了一个spring事务,那么在调用接下来的方法时是共用一个事务?还是新开一个事务呢?

Spring定义了7种传播行为

常见的有前三种
REQUIRED (默认传播行为),支持当前事务,如果当前没有事务,就新建一个事务。类似于重入锁,A方法和B方法都有事务,A方法调用B方法,A的事务会传递给B,使它们共用同一个事务,我起了个名字叫做重入事务。适用于:增删改查
SUPPORTS 如果存在一个事务,支持当前事务,如果没有事务,则非事务执行.适用于:查询
REQUIRES_NEW 开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起。适用于:内外部事务不存在关联的情况,比如log
MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常
NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务
NEVER 总是非事务地执行,不加入任何事务;
NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中。 如果没有活动事务, 则按 REQUIRED 属性执行。

事务失效场景,及其对应原因

  1. 自身调用问题:spring是通过aop的方式,对需要spring管理事务的bean生成了代理对象,然后通过代理对象拦截了目标方法的执行,在方法前后添加了事务的功能,所以必须通过代理对象调用目标方法的时候,事务才会起效。
  2. 非public方法导致的事务时效 Spring的事务代理通常是通过Java动态代理或CGLIB动态代理生成的,这些代理要求目标方法是公开可访问的public。
  3. 方法本身自己捕捉了异常,这样即使出现异常也不会触发事务的回滚,所以说要进行抛出,而不是自己捕捉。
  4. 造成事务回滚的异常一般是Error类异常或者是运行时异常,如果抛出的是检查型异常的话,那么不会造成事务回滚,所以我们可以将rollbackfor配置为Exception。
  5. 开启事务的bean没有交给spring容器管理。
  6. 数据库不支持事务。
  7. 事务传播设置的不对

事务失效原因分析

事务失效是因为未经过Spring代理

TODO 结合代码看 Spring事务实现原理

posted @ 2024-11-17 21:32  是笨小孩儿  阅读(19)  评论(0)    收藏  举报