【SpringBoot/MyBatis】单机数据库事务处理(不合理转账主动抛出自定义检查性异常使数据库回滚)

本文例程:https://files.cnblogs.com/files/heyang78/myBank_transactional_checkedException_210909_0616.rar

 本文涉及Springboot版本:2.5.4

前文 https://www.cnblogs.com/heyang78/p/15245291.html  讲述了抛出RuntimeException使数据库回滚的情况,但更好的方案是抛出自定义业务异常使得DB回滚。

 

要让Transactional标签遇到CheckedException也回滚,只需要在标签上加上点说明:

@Component
public class AccountService {
    @Resource
    private AccountMapper amapper=null;
    
    @Transactional(rollbackFor=Exception.class) 
    public void transfer(int amount,String fromAccount,String toAcccount) throws TransferException{
        int count=amapper.add(-amount, fromAccount);
        if(count==0) {
            throw new TransferException("对转出账户:"+fromAccount+"操作,更新记录数为0.只有可能是该账户不存在。");
        }
        
        count=amapper.add(amount, toAcccount);
        if(count==0) {
            throw new TransferException("对转入账户:"+toAcccount+"操作,更新记录数为0.只有可能是该账户不存在。");
        }
    }
}

有了上面标红字的部分,回滚机制就从出现RuntimeException回滚变成了CheckedException也回滚。

而TransferException是自定义的异常:

public class TransferException extends Exception{
    public TransferException(String msg) {
        super(msg);
    }
}

现在,只要TransferException一抛出,数据库就回滚了。

 

测试方法:

@SpringBootTest
class MyBankApplicationTests {

    @Autowired
    private AccountService aService;
    
    @Test
    void test() {
        try {
            aService.transfer(100, "001", "009");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

测试过后,由于009是不存在的账户,update语句会返回0,然后异常抛出,DB回滚,之前对001的账户修改会回滚,001账户里还是1000元。

关于数据库或函数细节请参考前篇:https://www.cnblogs.com/heyang78/p/15245291.html

--END--

posted @ 2021-09-09 06:27  逆火狂飙  阅读(113)  评论(0编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东