在研究并发请求商品超售问题时,测试了几种 MySQL 的 sql 语句,其中一种情况产生死锁的问题很困惑,求大佬指点。
SQL 语句
UPDATE inventory SET stock = stock - Y WHERE product_id = X AND stock >= Y;
product_id主键索引,此语句本意想避免超售,即 stock 库存不能为负。-
测试发现,当满足以下两种情况时,并发请求会死锁堵塞:
- 此 sql 语句放在事务内执行。
- stock 库存不足。
- 以上两种情况只满足其一,不会造成死锁。
对比 SQL
// 事务中,先对库存加锁 for update ,避免其他事务修改库存
SELECT stock FROM inventory WHERE product_id = X FOR UPDATE;
// 再进行修改
UPDATE inventory SET stock = stock - Y WHERE product_id = X;
- 如果换成这个 sql 语句不会出现死锁的堵塞。
请教下第一种 sql 是什么原因造成的死锁?