更多相关内容可查看
什么是乐观锁?
乐观锁是一种并发控制机制,它假设在大多数情况下,不会有冲突发生,因此允许多个事务同时访问相同的数据。乐观锁的核心思想是,在更新数据时,不会立即对数据进行加锁,而是在更新完成前进行检查,以确保在更新期间没有其他事务对数据进行了修改
为什么不用悲观锁?悲观锁又是什么?
在悲观锁中,当一个事务要访问某个数据时,会先对数据进行加锁,这样其他事务就无法同时修改该数据,直到锁被释放为止。这样可以确保数据的一致性,但也可能造成性能上的损失,因为其他事务在等待锁的释放时可能被阻塞。
举例:通俗意义上来讲,你访问一个网站的过程中,另一个人想要访问这个网站必须要等待你访问完,非常的不人性化
乐观锁的核心思想?
- 取出记录时,获取当前 version
- 更新时,带上这个 version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
通常,乐观锁的实现方式是在数据表中增加一个版本号(或时间戳)字段。在每次更新数据时,都会对版本号进行递增或更新。当一个事务要更新数据时,它会先读取数据和版本号,然后在更新时检查版本号是否与之前读取的版本号相同。如果相同,则表示在此期间没有其他事务对数据进行修改,可以继续更新;如果不同,则表示数据已经被其他事务修改,当前事务可能需要进行回滚或者重新尝试。
乐观锁的具体实现?
附git地址:https://gitee.com/its-a-little-bad/mybatisplus—chapter-1.git
数据库中添加version字段,并添加 @Version 注解
ALTER TABLE `user` ADD COLUMN `version` INT
实体类添加version字段
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;
元对象处理器接口添加version的insert默认值(可以新建一个Handler)
@Override
public void insertFill(MetaObject metaObject) {
......
this.setFieldValByName("version", 1, metaObject);
}
在 MybatisPlusConfig 中注册 Bean(创建配置类MybatisPlusConfig )
@Configuration
@MapperScan("com.atguigu.mpdemo1010.mapper")
public class MpConfig {
//乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
测试乐观锁可以修改成功
//测试乐观锁
@Test
public void testOptimisticLocker() {
//根据id查询数据
User user = userMapper.selectById(6);
//进行修改
user.setAge(200);
userMapper.updateById(user);
}
成功示例
本篇小结
个人理解:所谓的实现乐观锁的本质上,是通过一个版本号去实现事物的隔离性,在其中一个事务进行修改某一条数据的时候,另一个事物也在修改这一条数据,当第一个事物进行提交,会跟这条数据的版本号进行比对并进行+1,例如当前数据版本号为1,1=1数据修改成功并将版本号置为2,另一个同时修改数据的事物进行版本号比对1=2失败,数据修改失败