Transaction之坑:分析sql执行结果,主动促使事务rollback

Redis之坑:spring-data-redis中的Redis事务
Redis之坑:理解Redis事务
Redis之坑:Redis与MySQL中事务的区别
Transaction之坑:数据库事务
Transaction之坑:Spring中配置Transaction与不配置有何区别
Transaction之坑:分析sql执行结果,主动促使事务rollback


有关事务回滚的其他问题Spring事务回滚疑难详解


场景

JavaWeb开发,在开启事务的Service层方法中,编写业务逻辑时,经常会使用到如下两种方式:

  • 手动抛出异常(如果你没有配置 一般异常事务回滚,请抛出 RuntimeEception
int resultInt = merchantCollectMoneyMapper.updateMerchantBalance(pmsAppTransInfo);
if(resultInt != 1){
    logger.info("更新商户账户余额失败,商户ID:"+mercid +",结束时间:"+ UtilDate.getDateFormatter()+"。更新金额:"+ pmsAppTransInfo.getOrderamount());
    throw new RuntimeException("手动抛出");
}else{
   //修改流水表状态
}
  • 使用 TransactionAspectSupport 编程式实现手动回滚
int resultInt = merchantCollectMoneyMapper.updateMerchantBalance(pmsAppTransInfo);
if(resultInt != 1){
    logger.info("更新商户账户余额失败,商户ID:"+mercid +",结束时间:"+ UtilDate.getDateFormatter()+"。更新金额:"+ pmsAppTransInfo.getOrderamount());
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 
}else{
   //修改流水表状态
}

Summary:上述两种方式都是通过对 Dao|Mapper 执行结果分析,决定 transaction 是否 rollback


问题

  • 不是说TransactionManager 会根据service层方法throwsException自动 决定transaction回滚吗?
  • 那么还有必要分析SQL语句的执行结果吗?
    • 执行失败肯定会抛出异常,然后自动回滚的吧?

解决

  • 图1:一个 数据为空 的表
    这里写图片描述
  • 图2:使用不存在的主键执行 update 操作
    这里写图片描述

console:受影响的行:0

表明:
尽管SQL操作的数据行不存在,并不会有 Exception 抛出,结果仅仅是:
r e s u l t s = 0

summary:受影响的行为 0,同样意味着 业务逻辑执行失败,而且此时并不会产生 ExceptionTransaction 仍会被 commit,如果这个方法包含 一系列 write 操作,自然会产生 脏数据。显然这不是我们所期望的,所以,在这种情况下,我们需要分析SQL执行后的结果,来决定是否应该 主动 促使事务 rollback


猜你喜欢

转载自blog.csdn.net/qq_32331073/article/details/79866786