开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第30天,点击查看活动详情
Java开发中的乐观锁
介绍
悲观锁: 在修改数据时,总是认为别人会去修改同一条数据,所以每次操作时,都加上锁。
乐观锁: 在修改数据时,总是认为别人不会去修改同一条数据,所以每次修改时,不加锁,通过判断数据中的某一状态字段,来进行下面的操作。
CAS
乐观锁常见的实现方式是CAS和版本号,CAS,compare and swap,简单的讲就是在更新数据之前,判断一下数据是否被修改过,如果被修改过,则重试,如果没有被修改过,则直接更新。CAS包含了3个操作数
- 需要读写的内存位置V
- 进行比较的预期值A
- 拟写入的新值B
首先会判断内存位置V的值是否等于预期值A,如果等于,则将位置更新为新值B,如果不等于,则停止操作,但是很多CAS有有自旋操作,会一直重试。
CAS是由CPU支持的原子操作,其原子性是在硬件层面保证的。
版本号
第二种乐观锁实现方式是通过版本号,一般我们会在数据表中增加一个version字段,每次更新都带上version字段作为条件,并且在更新成功之后,将version字段+1并更新到数据库中,如果更新数据时的version条件和数据库中的不一致,则更新失败。
MybatisPlus乐观锁
- 首先我们需要配置乐观锁插件,这里演示一下Springboot注解方式
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
- 我们需要在数据库实体类上增加version字段,并且还需要加上MybatisPlus的@version注解
@Version
private Integer version;
- 此时我们调用mybatisplus的updateById,乐观锁即会生效,注意,mybatisplus目前乐观锁插件仅支持updateById和update方法,并且更新的时候version字段需要有值,否则乐观锁不会生效的。