zoukankan      html  css  js  c++  java
  • @Transactional注解的使用以及try-catch捕获异常导致@Transactional注解失效的问题

    1、事务管理是应用系统开发中必不可少的一部分。在spring boot 中,使用事务非常简单,只要直接在方法上面加入@Transactional 就可以实现。

    2、SpringBoot项目会自动配置一个 DataSourceTransactionManager,所以我们只需在方法(或者类)加上 @Transactional 注解,就自动纳入 Spring 的事务管理了。

    如下在方法加上 @Transactional 注解:

    @Transactional
    public void insertUser() {
        User user = new User("张三");
        userMapper.insertOneUser(user);          //向数据库插入一条记录
        throw new RuntimeException("发生异常");   //手动模拟抛出异常
    }
    

    抛出异常之后,事务会自动回滚,数据不会插入到数据库。

    • 当Transaction内发生unchecked exception的时候,会自动rollback,但是当Transaction内发生checked exception时,是不会自动rollback的。
    • 如果使用try-catch捕获异常,则该事务不会回滚。

    3、默认spring事务只在发生未被捕获的 RuntimeException 时才回滚。

    spring aop异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获RuntimeException的异常,但可以通过配置来捕获特定的异常并回滚。
    换句话说在service的方法中不使用try catch或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚。

    解决方案:

    • 方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理。

    • 方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常。

    例如

    catch (Exception e)
    {
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚
        result.put("status", 0);
        result.put("msg",msg);
        return result;
    }
    

    4、总结:如果是try-catch捕获异常引起的@Transactional注解失效,只要手动抛出RuntimeException()或者在catch中使用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句就可以解决。

    5、参考博客:

  • 相关阅读:
    【响应式Web设计实践 #BOOK#】
    【JS】(+﹏+)~
    -_-#【邮件】qq邮箱不显示图片
    -_-#【Markdown】
    51Nod——N1284 2 3 5 7的倍数
    51Nod——N1118 机器人走方格
    洛谷——P1014 Cantor表
    洛谷—— P1434 滑雪
    洛谷——P1443 马的遍历
    python(24)- 面向对象进阶
  • 原文地址:https://www.cnblogs.com/myblog001/p/13191729.html
Copyright © 2011-2022 走看看