红包并发下面的临界问题
来源:6-21 红包模块-抢红包应用服务层测试用例调试【调试方法和技巧】
qq_梦缘_3
2020-03-11
当库存还大于1的时候,假如剩余的金额为2元
// 那么在计算红包序列的时候是不会取最后剩余的所有金额的
//仍然是以数量大于1的情况下计算的,
// 比如有2个用户同时抢,分别计算得到0.8元和1.1元
//这时1.1元的用户获得红包,同时还剩余0.9元,并且库存是1
// 这个时候0.8元的用户也去抢,符合乐观锁的逻辑,也抢到0.8元,
// 然后库存剩余为0,但剩余金额为0.1元,之后由于库存为0了,
// 剩余金额就不能被抢走了
2回答
-
枫荇
2020-03-18
同学,你好,由于网路问题,没有提交成功,幸好截了图,将就一下吧。
00 -
枫荇
2020-03-18
你好同学,同一时间抢红包,一定是只有一个同学能拿到库存:
update red_envelope_goods
set remain_amount=remain_amount-CAST(? AS DECIMAL(30,6)),
remain_quantity=remain_quantity-1
where envelope_no=?
and remain_quantity>0
and remain_amount >= CAST(? AS DECIMAL(30,6))
同学,可以看一下上面的SQL中 `remain_quantity>0 ` ,只有剩余数量大于1的时候,这个语句才会执行。
也就是说,当剩余数量为1的时候,同时有2个用户抢红包时,在数据库层面不存在绝对并行,update语句会串行执行,那么就只有一个用户执行成功,失败的用户程序就会返回错误:
// - 如果更新失败,也就是返回0,表示无可用红包数量和金额,抢红包失败
if rows <= 0 || err != nil {
return errors.New("没有足够的红包和金额了")
}012020-03-18
相似问题