采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
当库存还大于1的时候,假如剩余的金额为2元 // 那么在计算红包序列的时候是不会取最后剩余的所有金额的 //仍然是以数量大于1的情况下计算的, // 比如有2个用户同时抢,分别计算得到0.8元和1.1元//这时1.1元的用户获得红包,同时还剩余0.9元,并且库存是1 // 这个时候0.8元的用户也去抢,符合乐观锁的逻辑,也抢到0.8元, // 然后库存剩余为0,但剩余金额为0.1元,之后由于库存为0了, // 剩余金额就不能被抢走了
同学,你好,由于网路问题,没有提交成功,幸好截了图,将就一下吧。
你好同学,同一时间抢红包,一定是只有一个同学能拿到库存:
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))
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("没有足够的红包和金额了")}
是我没有把问题描述清楚。当红包剩余个数为2,剩余金额为2元时,这个时候两个人同时抢,因为两个人读到的剩余个数都为2,所以都是随机一个金额出来,假设A随机出0.8元,B随机出0.9元,两个人都能更新数据库成功,最后红包商品的红包剩余个数为0,剩余金额为0.3元。我之前想的是锁住红包id,当有人在抢这个红包的时候,其他人来抢就需要等待。qq群里有同学提出预先生成好单个小红包放到redis里,利用redis的特性。也想多了解一下,在企业开发中,一般又是怎么处理
登录后可查看更多问答,登录/注册
Golang红包系统单体版+并发版+分布式+微服务版,四大金装版、超值必修课
4.2k 5
1.3k 1
965 15
2.2k 10
922 8