MySQL 乐观锁与悲观锁,解决库存问题

乐观锁

使用条件限制,实现乐观锁

假设库存 num=5
情况1(减库存成功)update 库存表 set num=num-5 where num-5 >= 0 and id=1; // 减5库存,影响行数1
情况2(减库存失败)update 库存表 set num=num-6 where num-6 >= 0 and id=1; // 减6库存,影响行数0

数据表加 version 字段,实现乐观锁

1)select id,version,num from 库存表 where id=1; // 假设取出 version=1
2)判断剩余库存 num 和要减的数量大小
3)update num=num-减的数量,version=version+1 from 库存表 where id=1 and version=1;

悲观锁

共享锁 lock in share mode

允许其他人读取资源,但是禁止其他人删除,修改资源。读多的场景。
1)select id,num from 库存表 where id=1 lock in share mode;
2)update num=num-减的数量 from 库存表 where id=1;

排他锁 for update

禁止别人读取,删除和更新这条资源,性能较低。写多的场景。
特别注意,在事务内使用务必 commit or rollback,事务不提交,for update 排他锁不会被释放。(由for update引发的血案 https://juejin.im/post/5cde18396fb9a037e92f07ab
对主键和unique字段进行for update操作的时候,mysql进行的是行锁,而对普通字段for update操作的时候进行的是表锁。
1)select id,num from 库存表 where id=1 for update;
2)update num=num-减的数量 from 库存表 where id=1;

发表新评论