CSDN话题挑战赛第2期
参赛话题:Java技术分享
【黑马程序员2022新版SSM框架教程_Spring+SpringMVC+Maven高级+SpringBoot+MyBatisPlus企业实用开发技术】
【一个问题】
业务并发现象带来的问题: 秒杀
【简单来说,乐观锁主要解决的问题是当前用户要更新一条记录的时候,希望这条记录没有被别人更新。】
乐观锁的实现方式
① 数据库表添加列
列名可以任意,比如使用version ,给列设置默认值为1


② 在模型类中添加对应的属性
根据添加的字段列名,在模型类中添加对应的属性值

③ 添加乐观锁的拦截器
package com.dingjiaxiong.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* ClassName: MpConfig
* date: 2022/9/24 15:21
*
* @author DingJiaxiong
*/
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//1 定义MP拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//2 添加乐观锁拦截器
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}
④ 执行更新操作,观察拦截器是否生效
@Test
void testUpdate(){
User user = new User();
user.setId(3L);
user.setName("Jock888");
userDao.updateById(user);
}

看看数据库

可以看到这次修改并没有更新version字段,原因是没有携带version数据。
“手动”添加version数据

发现传递的是1,MP会将1进行加1,然后,更新回到数据库表中。

所以要想实现乐观锁,首先第一步应该是拿到表中的version,然后拿version作为条件再将version加1更新回到数据库表中,所以在查询的时候,需要对其进行查询
@Test
void testUpdate(){
//1. 先通过要修改的数据id 将当前数据查询出来
User user = userDao.selectById(3L); //这个数据是带有version的
//2. 将要修改的属性逐一设置
user.setName("Jock888"); //所以这个数据就是有version的
userDao.updateById(user);
}
运行测试

【上面是咱们用眼睛看出来的version值,这次是查出来的】
查看数据库

原理就是这样。
【加锁模拟】
模拟A、B用户都来修改ID 为3 的这条数据。
//模拟多人修改
@Test
void testUpdate(){
//1. 先通过要修改的数据id 将当前数据查询出来
User user = userDao.selectById(3L); // 【A用户】 A 拿到的version = 3
User user2 = userDao.selectById(3L); // 【B用户】 B 拿到的version = 3
//先让B用户把值改了
user2.setName("Jock BBB用户改的"); //
userDao.updateById(user2); // 【这是B用户干的】 B用户操作完后,version = 4
//A 用户再改
user.setName("Jock AAA用户改的");
userDao.updateById(user); // 等到A 用户再进行操作,version = 3 这个条件就不成立了
}
运行测试
直接查看数据库

OK,这就很明显了,A 用户的修改操作并没有生效。
查看日志

这就是乐观锁。
MP 关于乐观锁的文档https://baomidou.com/pages/0d93c0/#optimisticlockerinnerinterceptor
【现在已经有插件 和 注解两种方式了】