Spring事务失效的场景

1.Spring只会对RuntimeException和Err的子类进行检查

原因:像检查异常它是不会回滚的.如:FileNotFoundException

解决办法:配置参数rollbackFor=异常类.class 指定检查异常 或者改成顶级Exception.class

2.业务内方法自己进行try-catch包住,导致不能正常回滚

原因:事务通知只有自己捕捉到了异常才能进行回滚处理,如果是自己处理的,就不会进行回滚.(相当于,事务的异常在最底层,如果外面的异常捕捉了,导致异常无法到最底层,所以底层不知道出现了异常)

解决办法:1.自己在catch块里面手动把异常抛出去,2.使用事务异常通知,也是在catch语句块里面加=>TransactionInterceptor.currentTransactionStatus().setRollbackOnly();

3.aop切面的顺序导致事务不能正确回滚

原因:事务的优先级最低,但是如果自定义的切面的优先级和他一样,则还是自定义切面在内层,这时如果抛出异常,被自定义的切面捕获了, 事务就没有收到异常通知,

解决办法:1.自己在catch块里面手动把异常抛出去,2.使用事务异常通知,也是在catch语句块里面加=>TransactionInterceptor.currentTransactionStatus().setRollbackOnly();(同2一致)

4.@Transactional 必须加在public方法上

原因:Spring默认@Transactional必须加在public方法上

5.父子容器导致事务失效

原因:在传统的ssm整合的时候会有两个容器,就会产生,有两个相同service

解决办法:不要用父子容器,springboot没有这个父子容器

6.调用本类方法导致传播行为失效,使用this或者直接调

原因:本类方法调用不经过代理,因此无法增强

解决办法:1.使用AopContext.currentProxy(),好像要配置什么东西.拿到代理对象.2.改变调用方式

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

在多线程情况下:你查询的时候,余额是够的,但是下面做了修改,修改过后并没有提交,,就是因为select不会让其他线程阻塞.

原因:事务的原子性仅包含insert.update.delete.select...forupdate语句,select方法并不会导致其他线程阻塞

解决办法:在你的select语句后面加上for update,它就不会查询当前正在执行的事务了

8.@Transactional方法导致的synchronized失效

原因:synchronized保证的仅是目标方法的原子性,环绕目标方法的还有commit操作,它们斌没有在sync块中=>synchronized方法只包含了方法本身,但是commit行为,并不在方法体内,所以会失效.

解决办法:1.扩大synchronized范围=>扩到到调用方,谁调用就把谁扩起来.2.select语句后面加上for update

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值