怎样解决商品锁定的问题?

设想淘宝的双十一有这样的情形:
十万人在同一时间内抢同一个商品。这时候由于并发量非常大,很可能有十个线程同时查到一个商品是未卖出的状态,这时候这些线程都以为这个商品还没有出售,结果十个人都买到了,而事实上,仅应该只有一个人抢到。。。请问,这种问题应该如何解决?

+++++++++++++++++++++++++++++++++++++++++++++++++
在实际生产环境里边,如果并发量不大且不允许脏读,可以使用悲观锁解决并发问题;但如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,所以我们就要选择乐观锁定的方法.
请问,有没有比使用乐观锁性能更好的方法呢??

阅读 5k
4 个回答

由于你没有举特定语言的例子,我就不写代码了。
但是无论哪种语言,都提供的有并发锁这样的特性,专门用来解决这种并发的实际场景。
如果不依赖变成语言,甚至数据库也有锁来应对这种场景。

究其底层实现,是在系统层面把多线程的调度归为一个线程,创建一个公共对象,比如互斥体等,在需要排斥锁的区域,放行某个线程,然后其他线程依次等待,排队进入。

归根结底是把异步执行变成了同步~


更新为集群
在集群环境下创建互斥体有点扯淡了,但是也不是没有办法,我们可以使用数据库,Redis等来替代互斥体,其他和上面不变。
另外,在集群环境下,可以使用第三方成熟的方案来实现,如zookeeperetcd

任务队列,异步排队执行锁库存,订单创建

在数据库层面,可以使用乐观锁或悲观锁,由于你提到并发量很大,所以建议使用乐观锁。

这里说一下怎样简单实现乐观锁:
在原表的基础上新增一个int version字段,然后update语句修改一下:

UPDATE table
SET ..., version = ? + 1
WHERE ..., version = ?

然后判断update语句的affected rows是否大于0,是则表示抢购成功,否则表示抢购失败。

假设有10个人同时读到同一条记录,这时候他们读到的version都是1,假设第1个人中最先update成功,他会把version值修改为2,然后剩下的九个人由于不满足WHERE version = 1,所以update语句的affected rows会等于0。

参考资料:http://www.cnblogs.com/guyufe...

建议使用分布式锁来解决,分布式锁常见方案有:基于Redis、基于Zookeeper的。在并发量大的情况下,使用数据库锁机制(乐观锁、悲观锁)都有性能问题,比如死锁问题,如果一个线程长期持有锁突然崩了,那么后续线程均无法获取锁,就会出现死锁问题。分布式锁参考资料:http://everbody.blog.163.com/...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进