MYSQL 并发情况下数据准确性方案

前言:

       我们经常遇到对数据进行的场景,比如库存扣减(设置库存)、订单信息更新(设置订单)等。以库存扣减为例我们的常用做法为:

1.查询当前仓库库存

select num from store where id=3

2.代码中判断当前库存是否大于需求库存如果大于需求库存则进行库存更新操作

if(num-需求库存>0)

待更新库存=num-需求库存

3.更新仓库库存

update store set num=${待更新库存} where id=3

假定当前仓库为5、需求库存为3 ,因符合条件则设置库存为2

上述有没有问题呢?

当然!假设同时有2个库存扣减请求并发执行,请求1需求库存为4、请求2需求库存为3,请求1获取仓库库存5符合库存更新条件,在请求1更新前请求2同样获取仓库库存5也符合库存更新条件,最后系统剩余库存要么更新为1要么更新为2,导致数据不一致(实际卖出了7个库存但是只扣除了4个或3个)

想解决这种问题我们可以考虑串行处理,但串行处理的性能是极低的尤其是互联网产品大并发及实时行要求高的情况下此方案简直就是竞争对手给你的建议!

哪如何解决呢这里提出三种方案

方案1:CAS

CAS(Compare And Set)

前言中最后一步更新操作的代码替换为:

update store set num=num-${待更新库存} where id=3 and num=${原num}

或者我们使用版本比较的方式校验数据有没有更新过,如果没有更新过则进行更新代码如下:

update store set num=num-${待更新库存} where id=3 and version=${原数据行版本}

但是使用行版本需要注意,必须保证任何更新操作都会引起行版本好的更新才可以,比如sqlserver的时间戳字段。但mysql的时间戳字段无法保证

此方案将避免因并发照成的库存多扣问题。

方案2:PAS

PAS(Permission And Set)

前言中最后一步更新操作的代码替换为:

update store set num=num-${待更新库存} where id=3 and num-${需求库存}>0

这样在满足实际库存大于需求库存的情况下所有的更新都会成功,大大提高了业务的通过率

优势:业务通过率最高变相的提升了执行效率


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值