Spring 事务的异常处理机制

 在service层的RuntimeException没有处理好导致了事务没有按照预期运行而是回滚了整个事务。


业务描述:在平台上,一位用户采取特殊手段跳过了前台的验证取款,通过浏览器的fetch取出大于自己钱包余额的amount。

  • sql:
    
        DECLARE ERROR_NEGATIVE_BALANCE CONDITION FOR SQLSTATE 'B0014';
    
        -- Check did all money deducted what supposed
    
        IF (amount_left > 0.00 || new_total_balance < 0.00) THEN
            SIGNAL ERROR_NEGATIVE_BALANCE
                SET MESSAGE_TEXT = 'NOT ENOUGH MONEY';
        END IF;
    因为我们的sql定义了对于amount负数的情况,将会抛出
    e.SQLState == 'B0014',我们在DAO层转换这个异常:
    
                } else if (e.SQLState == 'B0014') {
                    log.warn('[{}] [accountId: {}] not enough balance', method, accountId)
                    throw new NegativeBalanceException()

     

  • 在service层中处理这个异常:
     

                } catch (NegativeBalanceException e) {
                    cancelWithdrawal()
                    throw e
                }
    

    这就是我最开始的处理方法,把这个异常抛到control层想要打出一个log,写到这里我都不觉得有什么问题,直到后面运行才发现cancelWithdrawal()这个方法一直被回滚,后面仔细查看才发现。

  • /**
     * In case of balance goes below ZERO
     */
    class NegativeBalanceException extends RuntimeException {
    }

    问题就出在这里了,这个NegativeBalanceException是一个RuntimeException,我在service层catch到了这个异常没什么问题,错误就是处理完之后不应该抛出这个Exception,这就导致了在整个事务结束后抛出了一个RuntimeException被Spring发现,由于没有配置Spring中的@Transactional(rollbackFor = Exception.class)属性,默认是RuntimeException回滚,最终使得整个事务回滚。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值