php解决并发库存问题

一:问题
数据库处理sql是一条条处理的,假设购买商品的流程是这样的

时光疯子博客

当没有并发时,上面的流程看起来是如此完美,假设同时两个人下单,而库存只有1个了,在sql1阶段两个人查询到的库存都是>0的,于是最终都执行了sql2,库存最后变为-1,超售了,要么补库存,要么等用户投诉吧。
解决这个问题比较好的方法是什么呢?

二:解决问题
常规思路不外乎两种,一是加锁,二是利用队列。这里,我主要是通过对数据库加锁的方式来解决这个问题的。
1:乐观锁与悲观锁
数据库课程上接触到两个概念——共享锁和排它锁,现在又需要两个新的概念——乐观锁和悲观锁。

  • 乐观锁(Optimistic Lock),想法乐观,认为自己在操作数据库时不会发生冲突,取数据时不加锁,更新数据是加锁,进行判断。

  • 悲观锁(PessimisticLock),想法悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

显然乐观锁的相应速度快,悲观锁的时间消耗等都比较大。对于我们这个案例,使用这两种都是可以解决的。

三:锁的sql实现方式
1:乐观锁

//sql1:查询商品库存
update book set stock=2 where id=1 and stock=5;
update book set stock=2 where id=1 and stock=5;
//数据库执行 update语句有先后顺序
if(库存数量 > 0){
    //生成订单...
    sql2:库存-1
}
2:悲观锁
//sql1:查询商品库存
//对数据进行行锁,锁住查询的语句 只有在事务里面有效 commit 和 rollback 之后才能解锁
select  for update  
if(库存数量 > 0){
    //生成订单...
    sql2:库存-1
}


白俊遥博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论