写在前面:在设计新零售供应链wms(仓库管理系统)库存模块时,为了防止并发情况对库存的影响,查阅了一些资料,对InnoDB锁机制有了更全面的了解,在此做出分享,如有疏漏望不吝指正,愿共同进步!(此篇为1.0版本,后续随理解深入,会逐步迭代完善~)
博客搬家:https://segmentfault.com/a/1190000014133576
一、为什么要加锁
锁机制用于管理对共享资源的并发访问。
当多个用户并发地存取数据时,在数据库中就可能会产生多个事务同时操作同一行数据的情况,若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据的一致性。
一种典型的并发问题——丢失更新(其他锁问题及解决方法会在后面说到):
注:RR默认隔离级别下,为更清晰体现时间先后,暂时忽略锁等待,不影响最终效果~
时间点 | 事务A | 事务B |
---|---|---|
1 | 开启事务A | |
2 | 开启事务B | |
3 | 查询当前商品S库存为100 | |
4 | 查询当前商品S库存为100 | |
5 | 业务逻辑处理,确定要将商品S库存增加10,故更新库存为110(update stock set amount=110 where sku_id=S;) | |
6 | 业务逻辑处理,确定要将商品S库存增加20,故更新库存为120(update stock set amount=120 where sku_id=S;) | |
7 | 提交事务A | |
8 | 提交事务B |
异常结果:商品S库存更新为120,但实际上针对商品S进行了两次入库操作,最终商品S库存应为100+10+20=130,但实际结果为120,首先提交的事务A的更新『丢失了』!!!所以就需要锁机制来保证这种情况不会发生。
二、InnoDB锁类型概述
简介(后面会分别详细说到):
1、乐观锁与悲观锁是两种并发控制的思想,可用于解决丢失更新问题:
乐观锁会“乐观地”假定大概率不会发生并发更新冲突,访问、处理数据过程中不加锁,只在更新数据时再根据版本号或时间戳判断是否有冲突,有则处理,无则提交事务;
悲观锁会“悲观地”假定大概率会发生并发更新冲突,访问、处理数据前就加排他锁,在整个数据处理过程中锁定数据,事务提交或回滚后才释放锁&#