我是靠谱客的博主 务实毛衣,最近开发中收集的这篇文章主要介绍【电商吧 - 5】如何防止商品超卖前言一、如何防止超卖总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 前言
  • 一、如何防止超卖
    • 1、思路1
    • 2、思路2
    • 3、思路3
  • 总结


前言

      在多个人同时对一个商品下单时,如果处理的不得当会存在超卖的现象,这种严重的bug是无法接受的。这是一种极为常见的并发问题,这个时候就有开发者想到了通过锁来控制。但是由于很多小伙伴对于锁没有一个充分的认识,最后却弄巧成拙。如下,我列举一些常见的解决思路和我的想法,请大家参考。


一、如何防止超卖

      在防止超卖的逻辑编写时,加锁这个思路是没有问题的,但是要加什么锁,锁哪一段逻辑就成为了问题。

1、思路1

      jvm提供了synchronizedreentrantlock。这两个锁适合在减库存的时候使用吗?理论上讲,是可以使用的。但是服务必须是单机部署。如果是多台服务器,就会变成如下场景,锁根本没有作用。
在这里插入图片描述

2、思路2

      jvm锁弊端很明显,这时就会想到分布式锁,分布式锁实现的方法有很多。我列举了下redis和zk的实现及其对比。这种方式不管是单机还是集群中使用都是可以有效的防止超卖的。大概的思路是由redis的setNX命令实现进行加锁,加锁之后实现单线程减库存,这也算是一种相对较好的解决方式。

在这里插入图片描述

3、思路3

      我在网上曾看到有人列举前面两种实现方式,这里重点说明下,单机锁和分布式锁是不推荐的!
      其实防超卖最终的目的是防止数据库的库存(goods_num)小于0。导致小于0的原因是多个线程在程序中计算库存,然后在赋值给数据库。这么多锁要解决的问题,其实一条sql就可以实现。
update t_goods set goods_num=goods_num - 1 where goods_id=1 and goods_num>0
      如上所示。例如卖了id为1的商品1件。这时库存减一,重点是where条件中判断了goods_num>0。这样就间接的限制了只有库存在大于1的时候该sql才会减一。直接就防止了超卖的现象。其实这个时候应该就会有人抬杠了,这是电商场景呀,直接连接数据库压力很大的。其实这个时候就要在减库存之前进行友好的限流了。redis提供了几个命令。

  • incr——加
  • decr——减
  • incrby——阶梯加
  • decrby——阶梯减
    这几个都是原子操作,并且在执行成功之后会返回结果。例如:
redis> SET failure_times 10
OK
redis> DECR failure_times
(integer) 9

      这样如果有场景数据库减库存压力太大,可以双重判断,商品开卖之前,redis缓存商品的库存,先通过DECR减少redis库存,再减少数据库库存,当redis库存已经为0的时候,就没有必要再减少数据库的数据了。
在这里插入图片描述


总结

如上便是我的想法,如果您有更好的解决方式,欢迎点评。
xia

读到这里了,如果对你有帮助就留个赞吧。

另外关注公众号java内功心法回复我要当架构即可领取java方向必备进阶资料。
在这里插入图片描述

最后

以上就是务实毛衣为你收集整理的【电商吧 - 5】如何防止商品超卖前言一、如何防止超卖总结的全部内容,希望文章能够帮你解决【电商吧 - 5】如何防止商品超卖前言一、如何防止超卖总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部