您的位置:首页 > 数据库 > MySQL

mysql 针对高并发下,同时修改单条数据发生冲突导致数据错误的问题(例如:高并发下单,导致库存为负数)

2017-12-15 11:56 549 查看
毕业后第一次做的项目就是电商,但是当时也不明白这个问题。

所以给自己埋下一个坑。

先说说当初的做法,和遇到的问题。

//开启事务

start transaction;

//查询库存

select number from item where id = 1;

//如果大于购买数量进入购买,如果小于返回错误 并rollback

//进入购买

update item set item number = number - 1 where id = 1;

//如果成功commit 如果失败 rollback

问题:

当两个人 同时下单,同时进入事务  这个时候两个人查的数量是相同的,以下为模拟

步骤1=》用户1:查询item 数量为5

步骤2=》用户2:查询item 数量为5

步骤3=》用户1:买了五个将item的数量减5 并且成功

步骤4=》用户2:买了五个将item的数量减5 由于mysql的自身锁的问题 (因为用户1 没有提交 所以用户2 需要等待用户1 commit 才能真正的修改成功)

步骤5=》用户1:commit 成功修改数量并且成功购买

步骤6=》用户2:等待状态解除,将item的数量也成功减5 数量变为-5

错误:最后item为-5

解决的办法:

1.乐观锁:在每个用户commit 之前再重新查询 item的数量 如果为负数  rollback  并且说明库存不足

2.悲观锁:在查询的时候  select * from item where id = 1 改为  select * from item where id = 1 for update 进行锁定

  这个时候其他用户是无法查询到的。

这是目前理解的两种方法,不过不明白这里面的具体性能问题是怎么样的。也不清楚哪个方案更好。

在这里 也不讲述乐观锁和悲观锁了   因为本人也并不是完全理解 待我去寻摸一本书,弄明白了 在补充
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql