Mybatis plus中乐观锁的应用
乐观锁是什么?
乐观锁不是一个问题,它是一种针对特定问题的一个解决方案。主要解决丢失更新问题
丢失更新问题又是什么呢?
丢失更新就是两个不同的事务在某一时刻对同一数据进行修改。导致第一次操作数据丢失。
复杂的定义往往需要用朴实无华的例子来解释:
假设我们一个数据库中有一个数据表,记录着一个员工的工资
如下表所示:
id | salar | sex | age | … |
---|---|---|---|---|
1 | 10000 | 男 | 25 |
场景
某一天,同时有两个人对此数据表进行修改,如administrator1和administrator2(简称ad1和ad2),ad1的操作是将salar中的10000修改为20000(10000->20000),ad2的操作是将salar中的10000修改为5000(10000->5000)。
这里的同时并不是完完全全的同一时间(时分秒,毫秒、微秒都一样的那种),系统总会判定出一个先后顺序。我们这里假设ad1先执行成功。
ad1将10000改成20000之后,ad1开开心心的离开了。但是ad2随后的一番操作,使得ad1的salary最后还是变成了5000。这样ad1的更新操作就失效了,这就是丢失更新问题
我们如何解决这种问题呢?
我们采用这样的一种机制,在这个表中再添加一个标识字段,每更新一次数据,这个字段值就加1。这样在更新数据前检查此字段值是否发生改变,从而决定后续的操作
- 如果发生改变,则表明数据已经被修改,不允许接下来的修改
- 如果未发生改变,则表明此数据是第一次的修改,可以进行后续的修改操作。
(这个我感觉和git的那个代码上传差不多。如果代码不是最新拉取的,就不允许上传)
实践与应用
Mybatis plus中乐观锁的具体实现分为以下几个步骤:
- 在表中添加一个字段,作为版本号
- 在实体类中添加版本号的属性
- 在实体类中版本号属性上方添加注解 @Version
- 配置一个乐观锁的插件
详细操作
1、在表中添加一个字段,作为版本号
2、在实体类中添加版本号的属性
private Integer version;// 版本号
3、在实体类中版本号属性上方添加注解 @Version
@Version
private Integer version;// 版本号
4、配置一个乐观锁的插件
// 配置类
public class MpConfig {
//乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
还有一段关键代码,就是在执行插入方法的时候为version赋值为1
this.setFieldValByName(“version”,1,metaObject); // 在插入数据时自动为version 赋值为1,
具体实现
1、我们先往我们表中插入一条数据
@Test
void addUserWithTime(){
Date date = new Date();
User user = new User();
user.setUsername("test_version");
user.setAvatar("/test_version");
user.setPassword("version");
user.setEmail("163.com");
user.setStatus(0);
int insert = userMapper.insert(user);
System.out.println("insert的值是:"+insert);
}
我们可以看到version的值为1。
2、修改数据
我们将email的值163.com->qq.com,观察version值的变化
@Test
void testOptimisticLocker(){
// 一般情况是先查询,然后再做修改
// 根据id查询数据
User user = userMapper.selectById(9);
//进行修改
user.setEmail("qq.com");
userMapper.updateById(user);
}
}
这里看到,version的值变成了2
这样就设置了一个字段,用于更新前的比较。防止写入数据时出现丢失更新问题。
总结
- 首先介绍了什么是乐观锁。
- 接着从乐观锁中引出数据写入时的丢失问题。
- 最后介绍Mybatis plus中如何使用乐观锁。