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 进行锁定
这个时候其他用户是无法查询到的。
这是目前理解的两种方法,不过不明白这里面的具体性能问题是怎么样的。也不清楚哪个方案更好。
在这里 也不讲述乐观锁和悲观锁了 因为本人也并不是完全理解 待我去寻摸一本书,弄明白了 在补充
所以给自己埋下一个坑。
先说说当初的做法,和遇到的问题。
//开启事务
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 进行锁定
这个时候其他用户是无法查询到的。
这是目前理解的两种方法,不过不明白这里面的具体性能问题是怎么样的。也不清楚哪个方案更好。
在这里 也不讲述乐观锁和悲观锁了 因为本人也并不是完全理解 待我去寻摸一本书,弄明白了 在补充
相关文章推荐
- php解决下单、抽奖并发导致的库存负数的问题
- php解决下单、抽奖并发导致的库存负数的问题
- php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
- php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
- php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
- 如何避免mysql 主从同步中由于数据记录找不到和主键重复错误导致的同步异常问题
- 下单,抽奖并发导致的库存问题解决方案
- 解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
- php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
- EF+MySQL乐观锁控制电商并发下单扣减库存,在高并发下的问题
- php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
- 因为改 UOM conversion 导致库存数量和財务上的数据错误
- 修改初始化参数不合理导致数据不能启动问题解决
- mysql innodb 表无法删除/修改数据 错误:1205
- 配置一对多导致json转换错误,数据无法展现的问题
- MySQL删除更新数据时报1175错误的问题
- ef codeFirst 修改表结构 增加字段等 EF code first需要重新生成库导致数据丢失的问题.
- 针对各主流数据mysql、sqlserver、oracle中文乱码问题。
- mysql版本不同所导致SQL语句执行错误的问题
- 关于mysql 修改权限表user字段host导致权限丢失的问题