适用场景
为了解决丢失修改的问题,更新一条记录时,希望这条记录当前没有被别人修改,实现线程安全的数据更新
实现策略
添加version,版本号
取出记录时,获取当前version
更新时,带上version
执行更新时,set version = newVersion where version = oldVersion
如果version不对,更新失败
用MyBatis-Plus实现乐观锁
# mysql
version int null default null
# 实体类
@Version //版本号的注解
@TableField(fill= FieldFill.INSERT) //添加一个默认值
private Integer version;
# Mybatis-plus的配置类,com.atguigu.demomptest.config.MpConfig
// 说明这是一个配置类的注解
@Configuration
// 因为UserMapper要动态生成它的实现类对象,动态生成对象默认查找不到,所以使用Mapper扫描来查找
@MapperScan("com.atguigu.demomptest.mapper")
public class MpConfig {
/*配置乐观锁的插件*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
# com.atguigu.demomptest.handler.MyMetaObjectHandler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
// 添加时自动填充值
@Override
public void insertFill(MetaObject metaObject) {
//version默认值设置为1
this.setFieldValByName("version",1,metaObject);
}
}
# 测试类
@Test
public void testadd(){
User user=new User();
//没有设置id属性主键自增长,但mybatis-plus会使用主键策略自动生成id值
user.setName("lisi");
user.setAge(18);
user.setEmail("licy@163.com");
int insert=userMapper.insert(user);
System.out.println(insert);
}
//测试乐观锁
@Test
public void testOptimisticLocker(){
//根据id查询
User user=userMapper.selectById(1441561265146171394L);
//修改
user.setName("张三");
//这里不需要手动设置version值,因为mybatis-plus会自动将version值+1
//UPDATE user SET name=?, age=?, email=?, create_time=?, update_time=?, version=? WHERE id=? AND version=?
userMapper.updateById(user);
}
先添加一个user,它的版本号使用自动填充设置为1
再测试乐观锁,mybatis-plus会自动将版本号自增1