乐观锁
锁是用来解决业务并发现象带来的问题
乐观锁案例
- 加字段
- 实体类添加字段
- 拦截器
- 修改前获取对应的version
①:数据库表中添加锁标记字段, 默认值为1
②:实体类中添加对应字段,并设定当前字段为逻辑删除标记字段
package com.ieheima.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
//表明和实体类不对应
//@TableName("tbl_user")
public class User {
//适用数据库默认的生成策略生成ID IdType.ASSIGN_ID雪花算法生成策略
//@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
//字段名和实体类中定义的不同,select=false 表示不在查询语句中出现,起到保护隐藏密码的作用
@TableField(value = "pwd",select = false)
private String password;
private Integer age;
private String tel;
//数据库中不存在的数据
@TableField(exist = false)
private Integer online;
// 逻辑删除字段标记当前记录是否被删除
// @TableLogic(value = "0",delval = "1")
private Integer deleted;
//加乐观锁
@Version
private Integer version;
// 加锁的实现
// Update set abc = 1,Version = Version +1 Where vesion = 1
// select * form tbl_user limit 5,5 //MP分页功能(拦截器) 自动帮我们加入了代码 加入一个拦截器,一看你加入了update操作,自动帮你加入乐观锁
}
③:配置乐观锁拦截器实现锁机制对应的动态SQL语句拼装
package com.itheima.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpInterceptor() {
//1.定义Mp拦截器
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
//2.添加分页拦截器
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
//3.添加乐观锁拦截器
mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mpInterceptor;
}
}
④:使用乐观锁机制在修改前必须先获取到对应数据的verion方可正常进行
@Test
void testUpdate(){
//User user = new User();
//user.setId(1450553078976622594L);
//user.setName("Jock666");
UPDATE tbl_user SET name=? WHERE id=? AND deleted=0
可以看到直接更新:并不会对乐观锁拦截器不会对version字段修改
//userDao.updateById(user);
//1.先通过要修改的数据id将当前数据查询出来
//User user = userDao.selectById(1450553078976622594L);
2.将要修改的属性逐一设置进去
//user.setName("Jock888");
UPDATE tbl_user SET name=?, age=?, tel=?, version=?
WHERE id=? AND version=? AND deleted=0
//userDao.updateById(user);
//1.先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(1450553078976622594L);
User user2 = userDao.selectById(1450553078976622594L);
user2.setName("Jock aaa");
userDao.updateById(user2); //version -> 4
user.setName("Jock bbb");
userDao.updateById(user); //verion==3?条件还成立吗?
}
//整个操作的数据中必须要有带有version的操作,才能发现version。才会有锁机制。
//修改时version必须有收集,没有收集的话加不上锁机制
@Test
void testUpDate() {
/* //方法一
User user = new User();
user.setId(3L);
user.setName("yahui6");
user.setVersion(1);
userDao.updateById(user);*/
/* //方法二
//1.先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(3L);
//2.将要修改的属性逐一设置进去
user.setName("yahuiy2");
//查出来的数据一定带version,
userDao.updateById(user);*/
/*模拟A用户进来修改这个操作,模拟B用户进来修改这个操作*/
//1.先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(3L); //version=3
User user2 = userDao.selectById(3L); //version=3
user2.setName("jock aaa");
//查出来的数据一定带version,
userDao.updateById(user2); //version=4
//2.将要修改的属性逐一设置进去
user.setName("jock bbb");
//查出来的数据一定带version,
userDao.updateById(user); //version=3条件不成立了,所以这条修改一定会失效
}
乐观锁加入成功。来自学习笔记