闽公网安备 35020302035485号
第一个线程执行更新时
set version = newVersion where version = oldVersion newVersion = version+1 [2] oldVersion = version [1]
第二个线程执行更新时:
set version = newVersion where version = oldVersion newVersion = version+1 [2] oldVersion = version [1]假如这两个线程都来更新数据,第一个和第二个线程都可能先执行,假如第一个线程先执行更新,会把version改为2,第二个线程再更新的时候,set version = 2 where version = 1,此时数据库表的数据version已经为2,所以第二个线程会修改失败,假如第二个线程先执行更新,会把version改为2,第一个线程再更新的时候,set version = 2 where version = 1,此时数据库表的数据version已经为2,所以第一个线程会修改失败,不管谁先执行都会确保只能有一个线程更新数据,这就是MybatisPlus提供的乐观锁的实现原理分析。

@Data
//@TableName("tbl_user") 可以不写是因为配置了全局配置
public class User {
@TableId(type = IdType.ASSIGN_UUID)
private String id;
private String name;
@TableField(value="pwd",select=false)
private String password;
private Integer age;
private String tel;
@TableField(exist=false)
private Integer online;
private Integer deleted;
@Version
private Integer version;
}
步骤3:添加乐观锁的拦截器@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpInterceptor() {
//1.定义MybatisPlus拦截器
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
//2.添加乐观锁拦截器
mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mpInterceptor;
}
}
步骤4:执行更新操作@SpringBootTest
class Mybatisplus03DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testUpdate(){
User user = new User();
user.setId(3L);
user.setName("Jock666");
user.setVersion(1);
userDao.updateById(user);
}
}
你会发现,我们传递的是1,MybatisPlus会将1进行加1,然后,更新回到数据库表中。所以要想实现乐观锁,首先第一步应该是拿到表中的version,然后拿version当条件在将version加1更新回到数据库表中,所以我们在查询的时候,需要对其进行查询@SpringBootTest
class Mybatisplus03DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testUpdate(){
//1.先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(3L);
//2.将要修改的属性逐一设置进去
user.setName("Jock888");
userDao.updateById(user);
}
}
大概分析完乐观锁的实现步骤以后,我们来模拟一种加锁的情况,看看能不能实现多个人修改同一个数据的时候,只能有一个人修改成功。@SpringBootTest
class Mybatisplus03DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testUpdate(){
//1.先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(3L); //version=3
User user2 = userDao.selectById(3L); //version=3
user2.setName("Jock aaa");
userDao.updateById(user2); //version=>4
user.setName("Jock bbb");
userDao.updateById(user); //verion=3?条件还成立吗?
}
}
运行程序,分析结果: