• 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提交,则其他线程阻塞)

    在这里插入图片描述

  • 相关阅读:
    HTML人物介绍、个人设计web前端大作业、贝聿铭人物介绍(带报告3000字)
    校园安防智能视频行为分析预警系统解决方案
    EasyExcel 官网观看建议
    【SpringBoot系列教程-目录大纲】
    OpenCV C++案例实战二十七《角度测量》
    解决axios不发起请求的问题
    在华为云服务器上CentOS 7安装单机版Redis
    【Java】CAP理论以及它的实际应用案例
    多线程&并发篇---第十二篇
    Springboot毕设项目基于SpringBoot的图片网站f3yv9(java+VUE+Mybatis+Maven+Mysql)
  • 原文地址:https://blog.csdn.net/u014496893/article/details/126257039