乐观锁和悲观锁
如果没看懂。需要看下操作系统
模拟修改冲突
创建数据
CREATE TABLE t_product
(
id BIGINT(20) NOT NULL COMMENT '主键id',
NAME VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',
price INT(11) DEFAULT 0 COMMENT '价格',
VERSION INT(11) DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (id)
);
插入一条数据
INSERT INTO t_product (id, NAME, price) VALUES (1, '外星人', 100);
在pojo包下创建Product类
package com.example.pojo;
import lombok.Data;
@Data
public class Product {
private Long id;
private String name;
private Integer price;
private Integer version;
}
在mapper包下创建Productmapper接口
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.pojo.Product;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductMapper extends BaseMapper<Product> {
}
@Test
public void testProduct(){
//小李查询价格
Product productLi = productMapper.selectById(1);
System.out.println("小李查询的商品价格:"+productLi.getPrice());
//小王查询价格
Product productWang = productMapper.selectById(1);
System.out.println("小王查询的商品价格:"+productWang.getPrice());
//小李将商品价格+50
productLi.setPrice(productLi.getPrice()+50);
productMapper.updateById(productLi);
//小王将商品价格-30
productWang.setPrice(productWang.getPrice()-30);
productMapper.updateById(productWang);
//老板查询商品价格
Product productLaoan = productMapper.selectById(1);
System.out.println("老板查询的商品价格:"+productLaoan.getPrice());
}
最后查询结果
Mybatis-Plus的乐观锁插件
package com.example.pojo;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
@Data
public class Product {
private Long id;
private String name;
private Integer price;
@Version
//表示乐观符版本号字段
private Integer version;
}
package com.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加乐观锁
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
在运行,结果是老板查询价格是150
原因小李操作后,此时版本号是1,但小王操作时只是查询,并没有修改版本号,所以小王操作未成功
优化修改流程
@Test
public void testProduct(){
//小李查询价格
Product productLi = productMapper.selectById(1);
System.out.println("小李查询的商品价格:"+productLi.getPrice());
//小王查询价格
Product productWang = productMapper.selectById(1);
System.out.println("小王查询的商品价格:"+productWang.getPrice());
//小李将商品价格+50
productLi.setPrice(productLi.getPrice()+50);
productMapper.updateById(productLi);
//小王将商品价格-30
productWang.setPrice(productWang.getPrice()-30);
int result = productMapper.updateById(productWang);
if(result==0){
//操作失败,重试
Product productNew = productMapper.selectById(1);
productNew.setPrice(productNew.getPrice()-30);
productMapper.updateById(productNew);
}
//老板查询商品价格
Product productLaoan = productMapper.selectById(1);
System.out.println("老板查询的商品价格:"+productLaoan.getPrice());
}