Mybatis Plus 乐观锁

本文最后更新于:2024年9月8日 晚上

Mybatis Plus 乐观锁

乐观锁:故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,再次更新值测试。

悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!

  • 乐观锁实现方式。
    • 取出记录时,获取当前 version
    • 更新时,带上这个version
    • 执行更新时, set version = newVersion where version = oldVersion
    • 如果version不对,就更新失败。
1
2
3
4
5
6
7
8
-- 先查询,获得版本号 version = 1
-- A
update user set name = "test", version = version + 1
where id = 2 and version = 1
-- B
-- 线程抢先完成,这个时候 version = 2,会导致 A 修改失败。
update user set name = "test", version = version + 1
where id = 2 and version = 1

乐观锁插件

  • 实体类增加version字段。
1
2
@Version
private Integer version;
  • 注册乐观锁插件。
1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
@MapperScan(basePackages = {"com.lushan.tally.mapper"})
public class MybatisPlusConfig {

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}

}
  • 测试。
  • 模拟另外一个线程执行了插队操作,如果没有乐观锁就会覆盖插队线程的值。
1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void testOptimisticLocker(){
User user = userMapper.selectById(1L);
user.setName("test1");
user.setEmail("123456@qq.com");

User user2 = userMapper.selectById(1L);
user2.setName("test2");
user2.setEmail("123456@qq.com");
userMapper.updateById(user2);

userMapper.updateById(user);
}

说明

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity 中。
  • 仅支持 updateById(id)update(entity, wrapper) 方法。
  • update(entity, wrapper) 方法下, wrapper 不能复用!!!

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!