【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--