十可能也是因为这几天加班搞得头晕眼花的,一个很简单的逻辑在一个事务处理,竟然差点就写错了。
业务逻辑描述
用户去兑换奖品,需要做两个判断,1扣减用户积分,2扣减奖品库存。
代码逻辑
1、开启事务
2、检查积分是否足够
3、积分不够,返回
4、积分够,扣减积分
5、检查奖品库存
6、库存不够,返回
7、库存够,扣减库存
8、提交事务
写完后,总觉得哪里有点奇怪,后面仔细看了一下,发现若是6库存不够,返回,那用户积分又已经扣减了,是不是需要回滚,不能够提交事务?
然后想到是不是要改成如下逻辑:
1、开启事务
2、检查积分是否足够
3、积分不够,返回
4、积分够,扣减积分
5、检查奖品库存
6、库存不够,返回:触发事务回滚,让第4步的积分扣减失败。
7、库存够,扣减库存
8、提交事务
其实这个时候,已经钻进死胡同了,就想到解决办法,没有跳出来。如果按上面的操作,如果后面多加几个判断,岂不是每个地方都要促发回滚,比如spring来控制事务的话每个条件执行万后,如果不通过,都要手动抛出Runtime异常让spring事务捕获,那相当于是自己控制事务了,并且,最最最重要的是,代码会变得很恶心。
然后我跳出来想了一下,把数据库执行统一放到最后就可以了。逻辑如下。
1、开启事务
2、检查积分是否足够
3、积分不够,返回
4、积分够,继续执行
5、检查奖品库存
6、库存不够,返回
7、库存够,继续执行
8、扣减积分
9、扣减库存
10、提交事务
总结
在我们的业务逻辑中,如果涉及条件判断,不满足条件就维持原状的情况,数据库修改操作一定要统一在所有条件判断完后一起执行,这样子就不用面对后面条件判断不通过,事务要不要回滚的问题。