模拟问题场景
场景:
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(productWang);
}
//最终商品价格
Product product = productMapper.selectById(1);
System.out.println("最终商品价格:" + product);
}
结果:
标签:插件,priceWang,priceLi,Product,商品价格,productWang,Plus,productMapper,Mybatis From: https://www.cnblogs.com/1963942081zzx/p/17397718.html最终商品价格:Product(id=1, name=外星人笔记本, price=70, version=2)