Mybatis-Plus 插件——乐观锁
模拟问题场景
场景:
1.商品原先价格100
2.boss通知小李将商品价格加50
3.boss觉得加到150,价格太高,通知小王降价30
4.小李和小王同时查看商品价格为100,小李将价格改为150,小王将价格改为70
5.最终结果商品价格为70,而boss实际想设定的值是120
代码模拟问题:
@Test
public void testOptimisticLock() {
//小李查询商品价格
Product productLi = productMapper.selectById(1);
Integer priceLi = productLi.getPrice();
System.out.println("小李查询商品价格:" + priceLi);
//小王查询商品价格
Product productWang = productMapper.selectById(1);
Integer priceWang = productWang.getPrice();
System.out.println("小王查询商品价格:" + priceWang);
//小李涨价50
priceLi = priceLi + 50;
productLi.setPrice(priceLi);
productMapper.updateById(productLi);
//小王降价30
priceWang = priceWang - 30;
productWang.setPrice(priceWang);
productMapper.updateById(productWang);
//最终商品价格
Product product = productMapper.selectById(1);
System.out.println("最终商品价格:" + product);
}
结果:
最终商品价格:Product(id=1, name=外星人笔记本, price=70, version=0)
乐观锁解决问题
使用乐观锁中解决上述问题。
乐观锁实现方式:
- 取出记录时,获取当前 version
- 更新时,带上这个 version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
Mybatis-Plus 在使用乐观锁插件时,执行更新操作时会判断当前版本号是否和数据库一致,一致就执行更新操作,不一致的话可以重试(再查询一下数据,然后执行更新操作)
Mybatis-Plus 使用乐观锁:
- 配置类添加乐观锁插件
- 实体类版本号字段添加
@Version
注解
配置类添加乐观锁插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
实体类版本号字段添加@Version
@Data
public class Product {
private Long id;
private String name;
private Integer price;
@Version
private Integer version;
}
测试
/**
* 乐观锁解决问题
*/
@Test
public void testOptimisticLockPlus() {
//小李查询商品价格
Product productLi = productMapper.selectById(1);
Integer priceLi = productLi.getPrice();
System.out.println("小李查询商品价格:" + priceLi);
//小王查询商品价格
Product productWang = productMapper.selectById(1);
Integer priceWang = productWang.getPrice();
System.out.println("小王查询商品价格:" + priceWang);
//小李涨价50
priceLi = priceLi + 50;
productLi.setPrice(priceLi);
productMapper.updateById(productLi);
//小王降价30
priceWang = priceWang - 30;
productWang.setPrice(priceWang);
int i = productMapper.updateById(productWang);
if(i == 0) {
//重试
Product productWa = productMapper.selectById(1);
productWa.setPrice(productWa.getPrice() - 30);
productMapper.updateById(productWa);
}
//最终商品价格
Product product = productMapper.selectById(1);
System.out.println("最终商品价格:" + product);
}
结果:
最终商品价格:Product(id=1, name=外星人笔记本, price=120, version=2)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)