1.介绍
乐观锁(Optimistic Locking)和悲观锁(Pessimistic Locking)是两种常用的并发控制策略,它们在不同的应用场景下各有优势。这两种锁主要用于管理对共享资源的访问,以避免数据不一致的问题
2.例子
一件商品,成本价是80元,售价是100元。老板先是通知小李,说你去把商品价格增加50元。小 李正在玩游戏,耽搁了一个小时。正好一个小时后,老板觉得商品价格增加到150元,价格太
高,可能会影响销量。又通知小王,你把商品价格降低30元。
此时,小李和小王同时操作商品后台系统。小李操作的时候,系统先取出商品价格100元;小王 也在操作,取出的商品价格也是100元。小李将价格加了50元,并将100+50=150元存入了数据 库;小王将商品减了30元,并将100-30=70元存入了数据库。是的,如果没有锁,小李的操作就 完全被小王的覆盖了。
现在商品价格是70元,比成本价低10元。几分钟后,这个商品很快出售了1千多件商品,老板亏1 万多
采用乐观锁和悲观锁
如果是乐观锁,小王保存价格前,会检查下价格是否被人修改过了。如果被修改过 了,则重新取出的被修改后的价格, 150元,这样他会将120元存入数据库。
如果是悲观锁,小李取出数据后,小王只能等小李操作完之后,才能对价格进行操作,也会保证 最终的价格是120元。
3.springboot使用乐观锁
1.数据库加入version字段
2.使用乐观锁插件
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //添加分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); //添加乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }
3. 在实体类上加入Version字段以及注解@Version
@Version private Integer version;
4、悲观锁
4.1 概念
悲观锁认为冲突随时可能发生,因此在数据处理过程中始终保持数据锁定状态。悲观锁通过锁定数据的实际物理行或页来避免数据在读取、修改、写入过程中被其他事务访问,以此来保证数据的一致性和完整性。
4.2 适用场景
适合场景:写操作多,读操作少的场景,如金融交易系统
5. 乐观锁
5.1 概念
乐观锁认为冲突不太可能发生,因此在数据更新时才会去验证冲突是否发生。它通常是通过版本号(Version Number)或时间戳(Timestamp)来实现的,每次读取数据时,都会获取到这个版本号或时间戳,更新数据时,会比较版本号或时间戳是否一致,如果一致,则进行更新,并将版本号或时间戳加一;如果不一致,则说明数据已被其他事务修改,更新失败。
5.2 适用场景
适合场景:读操作远多于写操作的场景,如电商平台中的商品浏览与购买操作。
6. 总结
选择乐观锁还是悲观锁,主要取决于具体的应用场景和需求。如果写操作频繁,且对数据一致性要求极高,适合使用悲观锁;如果读操作远多于写操作,且对并发性能要求较高,适合使用乐观锁