Spring事务不生效的八大原因

1,221 阅读2分钟

1、抛出检查异常不能正确回滚

原因:Spring 事务管理默认回滚 RuntimeException
解决方案: @Transactional加属性rollbackFor(Exception.Class)

2、业务方法内自己try catch导致不能回滚

原因:声明式事务拿到的是代理对象,内部不抛出异常外部接收不到
解决方案:1、抛出异常 2、手动抛出TransactionalStatus.setRollbackOnly()

3、Aop切面顺序导致不会滚

原因:切面事务优先级最低,但自定义切面在其内层
解决方案:1、切面向上抛出异常 2、手动抛出异常TransactionalStatus.setRollbackOnly() 3、配置@Order进行加载排序

4、@Transactional只对公共方法生效

原因:@Transactional只对公共方法生效
解决方案:1、使用publick修饰 2、配置事务Bean对象使其对所有方法都生效

5、父子容器中子容器包扫描范围过大

原因:子容器扫描包范围过大
解决方案:1、各自在自己的范围内扫描各自的包 2、不要使用父子容器

6、调用本类方法导致事务传播行为失效

原因:本类方法没有经过代理类无法增强
解决方案:1、本类中注入自己 2、使用AopContext获取代理对象进行操作 3、通过CTW,LTW

7、@Transactional没有保证原子行为

原因:原子操作仅包含insert、update、delete、select...for update,select并不能保证事务的原子性
解决方案:使用select..for update只有第一个select事务提交第二个才能查出结果

8、@Transactional方法导致synchronized失效

原因:多线程情况下synchronized仅仅保证目标方法的原子性,环绕目标方法的还有commit操作并不在sync块内
解决方案:1、synchronized范围扩大到代理对象 2、使用select....for update