@Transactional注解事务不回滚的异常情况分析

欣喜 Spring 发布时间:2024-02-19 11:12:35 阅读数:631 1
下文笔者讲述@Transactional注解事务不回滚的异常分析,如下所示

@Transactional注解简介

@Transactional注解是Spring框架提供一个用于声明式事务管理的注解。
    它可应用在方法或类上,用于标识需要进行事务管理的方法或类。
   通过使用@Transactional注解,我们可以更加方便地管理事务,保障数据的一致性和可靠性
=====================================================
@Transactional注解的应用场景:
   @Transactional注解只能应用到public可见度的方法上
       可被应用于接口定义和接口方法
       方法会覆盖类上面声明的事务  

常见异常1:
遇到检查异常时,事务开启,也无法回滚

例:下面这段代码,用户依旧增加成功,并没有因为后面遇到检查异常而回滚
@Transactional
public int insertUser(User user) throws Exception{
    // 新增用户信息
    int rows = userMapper.insertUser(user);
    // 新增用户岗位关联
    insertUserPost(user);
    // 新增用户与角色管理
    insertUserRole(user);
    // 模拟抛出SQLException异常
    boolean flag = true;
    if (flag){
        throw new SQLException("发生异常了..");
    }
    return rows;
}
原因分析
     Spring的默认的事务规则是遇到运行异常(RuntimeException)和程序错误(Error)才会回滚
     如果想针对非检查异常进行事务回滚
     可在@Transactional 注解里使用 rollbackFor 属性明确指定异常
例:可正常回滚
@Transactional(rollbackFor = Exception.class)
public int insertUser(User user) throws Exception{
    // 新增用户信息
    int rows = userMapper.insertUser(user);
    // 新增用户岗位关联
    insertUserPost(user);
    // 新增用户与角色管理
    insertUserRole(user);
    // 模拟抛出SQLException异常
    boolean flag = true;
    if (flag){
        throw new SQLException("发生异常了..");
    }
    return rows;
}

常见异常2
在业务层捕捉异常后,发现事务不生效
这是许多新手都会犯的一个错误,在业务层手工捕捉并处理了异常,
你都把异常“处理”掉
Spring自然不知道这里有错,更不会主动去回滚数据

例:下面这段代码直接导致用户新增的事务回滚没有生效。
@Transactional
public int insertUser(User user) throws Exception{
    // 新增用户信息
    int rows = userMapper.insertUser(user);
    // 新增用户岗位关联
    insertUserPost(user);
    // 新增用户与角色管理
    insertUserRole(user);
    // 模拟抛出SQLException异常
    boolean flag = true;
    if (flag) {
        try{
            // 谨慎:尽量不要在业务层捕捉异常并处理
            throw new SQLException("发生异常了..");
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
    return rows;
}

笔者建议做法

@Transactional
public int insertUser(User user) throws Exception
{
    // 新增用户信息
    int rows = userMapper.insertUser(user);
    // 新增用户岗位关联
    insertUserPost(user);
    // 新增用户与角色管理
    insertUserRole(user);
    // 模拟抛出SQLException异常
    boolean flag = true;
    if (flag)
    {
        throw new RuntimeException("发生异常了..");
    }
    return rows;
}

Transactional注解常用属性表

属性 备注
propagation 事务的传播行为,默认值为 REQUIRED。
isolation 事务的隔离度,默认值采用 DEFAULT
timeout 事务的超时时间,默认值为-1,不超时。如果设置了超时时间(单位秒),那么如果超过该时间限制了但事务还没有完成,则自动回滚事务。
read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollbackFor 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。{xxx1.class, xxx2.class,……}
noRollbackFor 抛出 no-rollback-for 指定的异常类型,不回滚事务。{xxx1.class, xxx2.class,……}
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/Spring/202402/7986.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者