• spring事物失效场景及其解决方案


    一、错误的try catch导致事物不能回滚

    在catch中没有将异常抛出,因为事物通知只有捕捉到了目标抛出去的异常,才能进行后续的回滚处理,如果目标自己处理的异常,并没有抛出,事物通知是无法感知的。

    解决方案:

    方案一:异常原样抛出
    方案二:手动设置TransactionStatus.setRollbackOnly()
    在这里插入图片描述

    二、aop切面顺序导致事物不能正确回滚

    原因:事物切面优先级最低,但是日过自定义的切面的优先级和他一样,则还是自定义的切面在内层,这时若自定义的切面没用正确的抛出异常,事物则不能回滚
    解决方案:同上一个案例一样抛出异常即可。

    三、非public方法导致事物失效

    原因:spring为方法创建代理,添加0事物通知,前提都是该方法时public修饰的
    解决:改为public方法

    四、父子容器导致事物失效

    原因:子容器扫描的范围过大,把未添加事物配置的service扫描出来
    解决1:各扫描各的
    解决2:不要用父子容器,所有的bean都放在同一个容器里面
    父子容器只有在使用springMvc的这种老项目你们才会出现,使用springboot的项目都是一个容易,不会出现父子容器事物失效的情况。

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

    原因:本类方法调用不经过代理,因此无法增加,事物就会失效

    解决1:依赖注入自己的(代理)来调用,最简单的解决方案

    在这里插入图片描述

    解决2:添加开始代理对象的注解@EnableAspectJAutoProxy(exposeProxy=true),然后再代码中获取代理对象调用本类的方法

    在这里插入图片描述
    在这里插入图片描述

    六、@Transactional没有保证原子行为(多线程并发争抢同一个资源的时候会出现问题)

    原因:事物的原子性仅涵盖insert,update,delete,select… for update 语句,select方法并不阻塞

    解决1:通过synchrinazed保证目标方法的原子性

    在这里插入图片描述

    业务逻辑,先查询后两次更新

    在这里插入图片描述

    解决2:使用select… for update 替换select (排他锁,在做查询的时候,如果当前线程执行修改的语句没有commit提交,则其他线程阻塞)

    在这里插入图片描述

  • 相关阅读:
    Gartner公布《2023中国ICT技术成熟度曲线》,得帆信息入选低代码代表厂商
    【虹科分享】不要使用Windows解决方案来保护Linux服务器
    MPP和hadoop
    MySQL高级学习笔记(二)
    无代码开发成员入门教程
    5.3 端口扫描:Zenmap工具的应用
    Kafka入门到精通-阶段三(调优简介)
    元宇宙:区块链成熟的开始
    详解COCO数据格式的json文件内容
    【Java语言】遍历List元素时删除集合中的元素
  • 原文地址:https://blog.csdn.net/u014496893/article/details/126257039