防止商品超卖的 3 个思路!

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

前言

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


如下,我列举一些常见的解决思路和我的想法,请大家参考。


一、如何防止超卖

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


1、思路1

jvm提供了synchronized和reentrantlock。


这两个锁适合在减库存的时候使用吗?


理论上讲,是可以使用的,但是服务必须是单机部署。如果是多台服务器,就会变成如下场景,锁根本没有作用。


image.png


2、思路2

jvm锁弊端很明显,这时就会想到分布式锁,分布式锁实现的方法有很多。


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


image.png


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的时候,就没有必要再减少数据库的数据了。


image.png


总结

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


本文来自作者「叁滴水」投稿,谢谢分享,也欢迎爱好技术分享的各位技术朋友向「Java技术栈」投稿,让更多人看到,投稿方式:关注公众号「Java技术栈」在后台回复:投稿。


相关文章
|
监控 NoSQL Java
Redis之高并发超卖问题解决方案
在高并发的秒杀抢购场景中,常常会面临一个称为“超卖”(Over-Selling)的问题。超卖指的是同一件商品被售出的数量超过了实际库存数量,导致库存出现负数。这是由于多个用户同时发起抢购请求,而系统未能有效地控制库存的并发访问。
1305 0
|
缓存 NoSQL Redis
Redis高并发场景下秒杀超卖解决
Redis高并发场景下秒杀超卖解决
883 0
|
缓存 API Android开发
Android 应用优化策略:提升性能与用户体验
【4月更文挑战第21天】在移动应用开发领域,性能优化是一个持续的挑战。尤其对于Android平台,由于设备多样性和系统版本的碎片化,开发者需要采取多种策略确保应用流畅运行并给用户带来良好体验。本文将深入探讨针对Android应用的性能优化技巧,包括内存管理、UI渲染效率提升、多线程应用以及电池寿命优化等方面。这些建议旨在帮助开发者诊断和改进现有应用,或在开发新项目时提前考虑到性能因素。
|
Java Maven
关于 Could not find artifact ...:pom:1.0-SNAPSHOT 的问题!
关于 Could not find artifact ...:pom:1.0-SNAPSHOT 的问题!
3343 0
关于 Could not find artifact ...:pom:1.0-SNAPSHOT 的问题!
|
8月前
|
数据采集 监控 安全
代理IP全解析:从原理到自建代理池的实战指南
代理IP如同网络世界的“隐形斗篷”,能隐藏真实身份,保护隐私,突破访问限制,提升数据抓取效率。本文详解代理IP的核心价值、自建代理池的技术方案、运维策略及实战应用,助你掌握数字时代的生存技能。
741 0
|
7月前
|
JSON 数据可视化 API
淘宝/天猫:利用销售数据API生成区域热力图,优化仓储布局
本文详解如何利用淘宝/天猫销售数据API生成区域热力图,结合核密度估计与线性规划,科学优化仓储布局。通过数据驱动降低物流成本15%-20%,提升配送效率,助力电商高效运营。(238字)
356 0
|
11月前
|
消息中间件 数据可视化 Kafka
docker arm架构部署kafka要点
本内容介绍了基于 Docker 的容器化解决方案,包含以下部分: 1. **Docker 容器管理**:通过 Portainer 可视化管理工具实现对主节点和代理节点的统一管理。 2. **Kafka 可视化工具**:部署 Kafka-UI 以图形化方式监控和管理 Kafka 集群,支持动态配置功能, 3. **Kafka 安装与配置**:基于 Bitnami Kafka 镜像,提供完整的 Kafka 集群配置示例,涵盖 KRaft 模式、性能调优参数及数据持久化设置,适用于高可用生产环境。 以上方案适合 ARM64 架构,为用户提供了一站式的容器化管理和消息队列解决方案。
976 10
|
消息中间件 存储 负载均衡
kafka底层原理分析
kafka底层原理分析
400 2
|
监控 数据可视化 API
Elasticsearch 的实时监控与告警
【9月更文第3天】随着数据量的不断增加和业务复杂度的提升,对数据系统的实时监控和告警变得至关重要。Elasticsearch 作为一个高性能的搜索和分析引擎,提供了丰富的工具和插件来帮助用户实现实时监控和自动化告警。本文将详细介绍如何配置 Elasticsearch 以实现实时数据监控,并自动触发告警机制。
1488 3

热门文章

最新文章