首页 新闻 会员 周边 捐助

MySQL的InnoDB引擎下,库存超卖、事务、锁相关问题

0
[待解决问题]

update goods set good_num = good_num-1 where id = 37662;

在InnoDB引擎下,数据库执行上面sql语句时,理论上执认为是执行单条语句的事务 ,执行时会自动加写锁, 那么 在并发情况下, 大量执行了上面的sql语句后, 为何会出现超卖?

信仰沉思的主页 信仰沉思 | 初学一级 | 园豆:108
提问于:2020-05-20 01:11

大量执行是指并发执行吗?系统是分布式的吗?

哎哟,不错哦 4年前

@哎哟,不错哦: 并发执行,不是分布式的

信仰沉思 4年前

@信仰沉思: 一:调整数据库的隔离级别
二:update 语句加上代码块锁
推荐使用第二种方案

哎哟,不错哦 4年前

@哎哟,不错哦: 不能改隔离级别,单条的update自动会加锁

信仰沉思 4年前

@信仰沉思: update语句更新的时候是行级锁,如果这样不满足的话建议代码加锁

哎哟,不错哦 4年前

@哎哟,不错哦:现在主要是疑惑行级锁写锁不应该出现超卖。原因是什么

信仰沉思 4年前

@信仰沉思: 和隔离级别有关系并发情况下不建议使用数据库的锁来控制

哎哟,不错哦 4年前
< >
分享
所有回答(2)
0
update goods set good_num = good_num-1 where id = 37662 and good_num>=1

这样行吗

slowstart | 园豆:525 (小虾三级) | 2020-05-20 09:09

不行,100个库存会卖出订单商品数量累计超出100以上 , 依然会出现负数情况

支持(0) 反对(0) 信仰沉思 | 园豆:108 (初学一级) | 2020-05-20 11:51
0

建议在应用中控制并发。

保镖 | 园豆:759 (小虾三级) | 2020-05-20 09:25

在后端代码中怎么控制并发?

支持(0) 反对(0) 信仰沉思 | 园豆:108 (初学一级) | 2020-05-20 11:51

@信仰沉思: 比如根据你这个id加锁,同一时间只允许一个线程执行关于id为37662的update语句。
如果分布式系统,就用分布式锁。

支持(0) 反对(0) 保镖 | 园豆:759 (小虾三级) | 2020-05-20 11:54

@保镖: 不是用的数据库的读写锁?

支持(0) 反对(0) 信仰沉思 | 园豆:108 (初学一级) | 2020-05-20 11:58

@信仰沉思: 应用比数据库好控制。

支持(0) 反对(0) 保镖 | 园豆:759 (小虾三级) | 2020-05-20 12:00

@信仰沉思: 可以看看读写锁

支持(0) 反对(0) 保镖 | 园豆:759 (小虾三级) | 2020-05-20 12:05

@保镖: 对应用层的锁目前不了解, 现在在疑惑数据库写锁的原理

支持(0) 反对(0) 信仰沉思 | 园豆:108 (初学一级) | 2020-05-20 22:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册