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层方法throws
的Exception
来自动
决定transaction
回滚吗? - 那么还有必要分析SQL语句的执行结果吗?
- 执行失败肯定会抛出异常,然后自动回滚的吧?
解决
- 图1:一个
数据为空
的表
- 图2:使用
不存在的主键
执行update
操作
console: 受影响的行:0
-
表明:
-
尽管SQL操作的数据行不存在,并不会有
Exception
抛出,结果仅仅是: r e s u l t s = 0 results=0 results=0
summary: 受影响的行为
0
,同样意味着业务逻辑执行失败
,而且此时并不会产生Exception
,Transaction
仍会被commit
,如果这个方法包含一系列 write 操作
,自然会产生脏数据
。显然这不是我们所期望的,所以,在这种情况下,我们需要分析SQL执行后的结果,来决定是否应该主动
促使事务rollback
。