0

mysql 减库存并发问题

 2 years ago
source link: https://www.v2ex.com/t/816733
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  MySQL

mysql 减库存并发问题

  kikione · 1 小时 58 分钟前 · 362 次点击

减库存数量为 num

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

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

但是有什么弊端吗

11 条回复    2021-11-20 13:39:32 +08:00

sadfQED2

sadfQED2   1 小时 31 分钟前 via Android

可能减成负的呗

vvhhaaattt

vvhhaaattt   1 小时 27 分钟前 via Android

除非事务隔离是串行化,否则怎么看都会有问题吧
查询跟修改操作分两步走,并发时应该会库存少减,超卖吧

vvhhaaattt

vvhhaaattt   1 小时 23 分钟前 via Android

@vvhhaaattt 不对,单条语句似乎会加行锁,可能这么写也没问题?

zjsxwc

zjsxwc   1 小时 21 分钟前

有效解决并发数据一致性问题,我能想到就两种方式:
一种是用增量式记录的方式,每次数据获取(比如这里的库存)其实是根据历史记录“算”出来的,这里可以通过缓存中间计算、定时归档等方式加速“算”的速度,缺点是占用空间比较大。

一种就是单一队列方式,就是排队序列化处理,缺点是时间长速度慢。

dqzcwxb

dqzcwxb   1 小时 20 分钟前

跨库失效,多表失效
要解决并发只能是 redis 或者队列串行处理

bigbyto

bigbyto   1 小时 11 分钟前 via iPhone

为啥都在顾左右而言他?我认为这条是没问题的,你那条 sql 会给 id 为 1 的索引加 X Lock ,其他事务想修改必须等你释放锁,因此在默认的隔离级别下是可以保证一致性的。

除了 READ_UNCOMMITED 不行,其他隔离级别应该都没问题。

zjsxwc

zjsxwc   59 分钟前

@bigbyto
数据库确实没问题,
但感觉业务上会出错,楼主这条 sql 就表示数据库能减去库存就减去库存值,但卖我仍旧业务上照样卖,这在业务上好像不能接受。

sagaxu

sagaxu   49 分钟前 via Android

@zjsxwc 业务是知道减库存失败的,为什么还要照卖?

zjsxwc

zjsxwc   46 分钟前

@sagaxu 哦哦 ,可以 通过 查看执行后 affected rows count 判断是否失败
```
update mytable set inventory = inventory-num WHERE id= 1 and inventory >=num
```

huang119412

huang119412   34 分钟前

update 本来就可以当成分布式锁。直接更新不就是悲观锁?缺点是并发低,竞争大。而且你要理解 rows affected ,rows matched 的区别。

mazyi

mazyi   11 分钟前 via iPhone

update 就是锁呀,实现业务没问题,就是可能效率有问题,所以才想那么多 cache 提前处理

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK