mysql 减库存并发问题

2021-11-20 11:51:43 +08:00
 kikione

减库存数量为 num

update mytable set inventory = inventory-num WHERE id= 1 and inventory >=num

这样减库存不用加乐观锁和悲观锁,也可以是吧

但是有什么弊端吗

5802 次点击
所在节点    MySQL
47 条回复
sadfQED2
2021-11-20 12:19:33 +08:00
可能减成负的呗
vvhhaaattt
2021-11-20 12:23:18 +08:00
除非事务隔离是串行化,否则怎么看都会有问题吧
查询跟修改操作分两步走,并发时应该会库存少减,超卖吧
vvhhaaattt
2021-11-20 12:27:00 +08:00
@vvhhaaattt 不对,单条语句似乎会加行锁,可能这么写也没问题?
zjsxwc
2021-11-20 12:29:20 +08:00
有效解决并发数据一致性问题,我能想到就两种方式:
一种是用增量式记录的方式,每次数据获取(比如这里的库存)其实是根据历史记录“算”出来的,这里可以通过缓存中间计算、定时归档等方式加速“算”的速度,缺点是占用空间比较大。

一种就是单一队列方式,就是排队序列化处理,缺点是时间长速度慢。
dqzcwxb
2021-11-20 12:30:21 +08:00
跨库失效,多表失效
要解决并发只能是 redis 或者队列串行处理
bigbyto
2021-11-20 12:39:28 +08:00
为啥都在顾左右而言他?我认为这条是没问题的,你那条 sql 会给 id 为 1 的索引加 X Lock ,其他事务想修改必须等你释放锁,因此在默认的隔离级别下是可以保证一致性的。

除了 READ_UNCOMMITED 不行,其他隔离级别应该都没问题。
zjsxwc
2021-11-20 12:50:48 +08:00
@bigbyto
数据库确实没问题,
但感觉业务上会出错,楼主这条 sql 就表示数据库能减去库存就减去库存值,但卖我仍旧业务上照样卖,这在业务上好像不能接受。
sagaxu
2021-11-20 13:00:51 +08:00
@zjsxwc 业务是知道减库存失败的,为什么还要照卖?
zjsxwc
2021-11-20 13:04:08 +08:00
@sagaxu 哦哦 ,可以 通过 查看执行后 affected rows count 判断是否失败
```
update mytable set inventory = inventory-num WHERE id= 1 and inventory >=num
```
huang119412
2021-11-20 13:15:58 +08:00
update 本来就可以当成分布式锁。直接更新不就是悲观锁?缺点是并发低,竞争大。而且你要理解 rows affected ,rows matched 的区别。
mazyi
2021-11-20 13:39:32 +08:00
update 就是锁呀,实现业务没问题,就是可能效率有问题,所以才想那么多 cache 提前处理
IvanLi127
2021-11-20 14:12:51 +08:00
我感觉没啥问题
markgor
2021-11-20 14:14:36 +08:00
該說的上面都說了,
num 只要前面有做判斷一般都沒問題,(如傳入負數)。
Jooooooooo
2021-11-20 14:14:59 +08:00
这条语句没问题

就是效率会有问题, 一万个人同时来减就卡死了

一般都会放在缓存里面过一道
documentzhangx66
2021-11-20 15:28:00 +08:00
真正的生产系统,业务流程代码,需要考虑:

1.健壮性
比如数据库、子业务系统突然崩溃;比如机房停电。

2.可调试性
某个环节出了 bug ,系统设计上需要做到在最短时间内,通过某种方式进行 bug 追踪。

3.记录日志
比如细化的日志级别,连 if else 或 switch case 走的是哪条分支,都需要记录。

以上这些功能,在流程设计与实现时,还需要考虑事务成功与失败时的处理方案,需要考虑并行时如何按顺序操作资源来确保不发生死锁,需要考虑如果某个环节出现了性能瓶颈应该如何处理,等等。

这就是为什么真正健壮的系统,一个简单的业务操作,数据库的业务 SQL 都可以有上千行的原因。
leafre
2021-11-20 15:40:25 +08:00
这句话就是乐观锁
缺点就是高并发大部分都是失败,一般不采用
什么你说不是高并发?那为什么用锁
fgwmlhdkkkw
2021-11-20 16:26:22 +08:00
@documentzhangx66 😅😅😅😅😅😅😅😅😅😅😅
kikione
2021-11-20 16:42:04 +08:00
@Jooooooooo 没有那么高的并发,同时有 10 个人就不错了
kikione
2021-11-20 16:43:22 +08:00
@leafre 也不是高并发,但是 update 不是都带锁么,不是我用不用锁的问题吧
jsdi
2021-11-20 16:44:10 +08:00
没啥问题 但是 update 是当前读,会加悲观锁,也就是写锁,效率上会有问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/816733

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX