try{}catch{}中事务不回滚

使用@Transactional 程序里面添加了try{}catch{}中事务就不回滚

    @Transactional
    public void splitExcuteSql(String sqlStr) {
        // 去掉\t\n\r等内容
        String[] split = sqlStr.split(";");
        List<String> sqlList = new ArrayList<>(Arrays.asList(split));

        String excuteSql;
        try {
            for (String sql : ListUtils.emptyIfNull(sqlList)) {
                if (StringUtils.isNotBlank(sql)) {
//                    executeSqls(sql.trim()); // 执行sql
                }
            }
        } catch (Exception e) {
            String message = e.getMessage();
            if (message.contains("PRIMARY")) {
                message = message + " 主键重复,请增大序列当前值,再进行插入!";
            }
            // 手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException(message);
        }
    }

为什么呢?因为方法上未加任何属性的@Transactional注解只能在抛出RuntimeException或者Error时才会触发事务的回滚,常见的非RuntimeException是不会触发事务的回滚的。

 如果要在抛出 非RuntimeException时也触发回滚机制,需要我们在注解上添加 rollbackFor = { Exception.class }属性。

使用@Transactional(rollbackFor = { Exception.class }),抛出捕获的非RuntimeException异常
方法上使用@Transactional(rollbackFor = { Exception.class })注解声明事务回滚级别,在捕获到异常时在catch语句中直接抛出所捕获的异常。

/**
     *  分离sql和执行sql
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void splitExcuteSql(String sqlStr) {
        // 去掉\t\n\r等内容
        String repalceSqlStr = replaceSpecialBlank(sqlStr);
        String[] split = sqlStr.split(";");
        List<String> sqlList = new ArrayList<>(Arrays.asList(split));
        
        String excuteSql;
        try {
            for (String sql : ListUtils.emptyIfNull(sqlList)) {
                if (StringUtils.isNotBlank(sql)) {
//                    executeSqls(sql.trim()); // 执行sql
                }
            }
        } catch (Exception e) {
            String message = e.getMessage();
            if (message.contains("PRIMARY")) {
                message = message + " 主键重复,请增大序列当前值,再进行插入!";
            }
            // 手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException(message);
        }

    }

    // 去掉 回车、换行符、制表符
    private String replaceSpecialBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("[\t\r\n]");
            Matcher m = p.matcher(str);
            dest = m.replaceAll(" ");
        }
        return dest;
    }

上面代码包括了处理方式:

1,@Transactional(rollbackFor = { Exception.class }),抛出捕获的非RuntimeException异常

2, 手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

3,抛出运行时异常:throw new RuntimeException(message);

总结:

如果这三种方式都不管用的时候,可以在调用该方法的方法,加@Transactional

@Transactional
public void uploadSqlFile(MultipartFile file, String oper, String createType) throws Exception {
    String sqlStr = replaceUploadSql(file, createType);
    splitExcuteSql(sqlStr);
}

在上一个方法添加@Transactional,不管调用的方法如何,有报错就会执行回滚。也就不用管是否加了try{}catch{}。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值