1、概述
应用场景:当要更新一条记录的时候,希望这条记录没有被别人更新
悲观锁
和乐观锁
区别:
- 悲观锁: 悲观的认为我要修改的数据一定会被他人修改,如果我要修改数据,我就会给数据上锁,别人都不能去修改,我修改完之后别人才可以修改
- 乐观锁:乐观的认为我修改的数据别人别人不会去改,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制(version)和CAS算法实现
两种锁适用场景
乐观锁适用于写少读多
的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量
悲观锁适用于写多读少
,多写,一般会经常产生冲突,这就会导致上层应用会不断的进行重试,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。
阿里巴巴建议以冲突概率20%这个数值作为分界线来决定使用乐观锁和悲观锁,
虽然说这个数值不是绝对的,但是作为阿里巴巴各个大佬总结出来的也是一个很好的参考。
2、实现(两步)
2.1 插件配置
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
2.2 注解实体字段 @Version 必须要!
实体类User添加 字段version
<font color='red'>同时数据库记得添加version字段</font>
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id=null;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 邮箱
*/
private String email;
@Version
private Integer version;
}
UserController
业务:id为n的一行数据的年龄age +1的操作
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService service;
@RequestMapping("/lock")
public void lock(Integer id){
User byId = service.getById(1);
User user = new User();
user.setId(1);
user.setAge(byId.getAge()+1);
user.setVersion(byId.getVersion());
boolean b = service.updateById(user);
if (b){
System.out.println("-----------+++++++++++年龄增加成功++++++++++++++++++++++++++++--");
}else{
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试");
}
}
}
测试类:
模拟开启50个线程模拟同时对id为n的数据操作
@Autowired
private TestRestTemplate testRestTemplate;
@Test
//测试乐观锁
void testLock() {
String url = "http://localhost:8080/user/lock";
for (int i = 0; i <50 ; i++) {
new Thread(()->{
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("id","1");
String result = testRestTemplate.postForObject(url, params, String.class);
}).start();
}
}
测试结果:
数据库增加的年龄对应, 没有多+也没有少+
-----------+++++++++++年龄增加成功++++++++++++++++++++++++++++++++++++----------------------------------------
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
-----------+++++++++++年龄增加成功++++++++++++++++++++++++++++++++++++----------------------------------------
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
-----------+++++++++++年龄增加成功++++++++++++++++++++++++++++++++++++----------------------------------------
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
-----------+++++++++++年龄增加成功++++++++++++++++++++++++++++++++++++----------------------------------------
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
代码地址:https://github.com/jw-star/mybatis-plusDemo/tree/master/mybatisplusdemo
相关文章:
SpringBoot之【mybatisplus】快速上手
SpringBoot之【mybatisplus】代码生成器
SpringBoot之【mybatisplus】分页插件、条件查询、sql打印开启
SpringBoot之【mybatisplus】乐观锁