PostgreSQL 并发问题:下单之前检查商品数量是否足够,如果足够则购买后数量递减

2016-06-01 14:04:51 +08:00
 TangMonk

用的默认的 Read Committed 并发控制,会不会出现多余的订单?

比如说现在有 100 个订单,会不会出现 100+个订单?

2037 次点击
所在节点    问与答
23 条回复
ipconfiger
2016-06-01 14:10:33 +08:00
要用 Serializable 才行
TangMonk
2016-06-01 14:16:40 +08:00
@ipconfiger 读取数量和递减数量的时候都用 Serializable 吗?
tabris17
2016-06-01 14:22:55 +08:00
update product set inventory=inventory-1 where product_id=123 and inventory>=1
TangMonk
2016-06-01 14:24:28 +08:00
@tabris17 默认就是这样的。。
tabris17
2016-06-01 14:38:03 +08:00
@TangMonk 你是说先 select 出 inventory ,然后 update 语句里不判断 inventory ?那必须 Serializable 隔离级别或者加锁
TangMonk
2016-06-01 14:43:22 +08:00
@tabris17 恩,对,先 select 出数量,然后再 update, 并且没有判断数量>=1 。
TangMonk
2016-06-01 14:44:25 +08:00
@tabris17 今天出现了这个问题,系统预先设置了 1000 个库存,然后后台发现 1008 个订单。。但是商品的数量还是为 0 ,并没有为-8 。。
tabris17
2016-06-01 14:54:49 +08:00
@TangMonk 如果是 set inventory=inventory-1 不会出现这种情况,除非你是 set inventory=?
jjx
2016-06-01 15:01:52 +08:00
版本机制

或用队列

最安全的就是队列+版本机制
imzshh
2016-06-01 15:05:18 +08:00
关键词: select for update
TangMonk
2016-06-01 15:05:52 +08:00
@tabris17 的确,用的就是 set inventory=?
TangMonk
2016-06-01 15:06:27 +08:00
@imzshh 谢谢,我搜下
TangMonk
2016-06-01 15:10:10 +08:00
@imzshh FOR UPDATE 不会锁住 SELECT 吗?只会锁 UPDATE , DELETE 和 FOR UPDATE 吗?
TangMonk
2016-06-01 15:13:09 +08:00
FOR UPDATE 貌似要比 Serializable 好用点
TangMonk
2016-06-01 15:21:51 +08:00
@tabris17 为什么 set inventory=inventory-1 不会出现这种情况呢
imzshh
2016-06-01 15:21:52 +08:00
@TangMonk 你自己做些测试吧,因为这个要配合事务一起用的,所以实现的时候要考虑的东西还挺多的,程序异常,死锁之类的。
TangMonk
2016-06-01 15:27:23 +08:00
@imzshh 好的,谢谢
tabris17
2016-06-01 15:29:52 +08:00
@TangMonk 因为字段自减是原子操作
TangMonk
2016-06-01 16:53:34 +08:00
@tabris17 刚才我开了几个线程请求测试了下,貌似不行,库存为 1000 ,库存递减到 0 的时候,才生成了 500 多个订单。。。

我换成 FOR UPDATE , 测试了下没有问题了。

看来要得好好补习下 MVCC 了
TangMonk
2016-06-01 16:54:29 +08:00
@TangMonk 读和写的都用 FOR UPDATE 锁住了

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

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

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

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

© 2021 V2EX