主要适用场景
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = yourVersion+1 where version = yourVersion
- 如果version不对,就更新失败
乐观锁配置需要2步 记得两步
1、插件配置
spring xml
<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"/>
spring boot
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
2、注解实体字段@Version 必须要!
public class User {
@Version
private Integer version;
...
}
特别说明: 仅支持 int,Integer,long,Long,Date,Timestamp
示例
1、UpdateById
@Test
public void testUpdateByIdOptLock() {
Long id = 991L;
H2UserIntVersionExtendTO user = new H2UserIntVersionExtendTO();
user.setId(id);
user.setName("991");
user.setAge(91);
user.setPrice(BigDecimal.TEN);
user.setDesc("asdf");
user.setTestType(1);
user.setVersion(1);
userService.insertAllColumn(user);
H2UserIntVersionExtendTO userDB = userService.selectById(id);
Assert.assertEquals(1, userDB.getVersion().intValue());
userDB.setName("992");
userService.updateById(userDB);
userDB = userService.selectById(id);
Assert.assertEquals(2, userDB.getVersion().intValue());
Assert.assertEquals("992", userDB.getName());
}
2、UpdateByEntityWrapper
@Test
public void testUpdateByEntityWrapperOptLock() {
Long id = 992L;
H2UserIntVersionExtendTO user = new H2UserIntVersionExtendTO();
user.setId(id);
user.setName("992");
user.setAge(92);
user.setPrice(BigDecimal.TEN);
user.setDesc("asdf");
user.setTestType(1);
user.setVersion(1);
userService.insertAllColumn(user);
H2UserIntVersionExtendTO userDB = userService.selectById(id);
Assert.assertEquals(1, userDB.getVersion().intValue());
H2UserIntVersionExtendTO updUser = new H2UserIntVersionExtendTO();
updUser.setName("999");
userService.update(updUser, new EntityWrapper<H2UserIntVersionExtendTO>()); //这里有问题这样做version根本拿不到,et是空的。
userDB = userService.selectById(id);
Assert.assertEquals(1, userDB.getVersion().intValue());
Assert.assertEquals("999", userDB.getName());
updUser.setVersion(1);
updUser.setName("998");
userService.update(updUser, new EntityWrapper<H2UserIntVersionExtendTO>());
userDB = userService.selectById(id);
Assert.assertEquals(2, userDB.getVersion().intValue());
Assert.assertEquals("998", userDB.getName());
}
官方文档:https://baomidou.gitee.io/mybatis-plus-doc/#/optimistic-locker-plugin
使用UpdateByEntityWrapper就有问题,怎么都没法更新version,查看乐观锁的实现原理才发现。如果传入的entity为空,直接不走乐观锁的逻辑。
所以使用的时候需要,先查出entity,然后在塞入新建的wrapper中。
//这里从数据库查出最新的entity,里面带有最新的version的
H2UserIntVersionExtendTO userDB = userService.selectById(id);
Assert.assertEquals(1, userDB.getVersion().intValue());
H2UserIntVersionExtendTO updUser = new H2UserIntVersionExtendTO();
updUser.setName("999");
//这里新建entityWrapper时,需要传入查询出的entity,这里很重要!!!
userService.update(updUser, new EntityWrapper<H2UserIntVersionExtendTO>(userDB));