赞
踩
在面试过程中,我们经常会被问道乐观锁,悲观锁!这个其实非常简单!
我们这里主要讲解 乐观锁机制!
乐观锁实现方式:
set version = newVersion where version = oldVersion
乐观锁:1、先查询,获得版本号 version = 1
– A
update user set name = "kuangshen", version = version + 1
where id = 2 and version = 1
– B 线程抢先完成,这个时候 version = 2
,会导致 A 修改失败。
update user set name = "kuangshen", version = version + 1
where id = 2 and version = 1
在对应的entity
实体类中编写字段、
@Version //乐观锁Version注解
private Integer version;
需要在config
包下 的配置类中编写代码,注册乐观锁插件。
// 扫描我们的 mapper 文件夹
@MapperScan("com.kuang.mapper")
@EnableTransactionManagement
@Configuration // 配置类
public class MyBatisPlusConfig {
// 注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
在测试类@Test
中编写测试代码:
// 测试乐观锁成功!
@Test
public void testOptimisticLocker(){
// 1、查询用户信息
User user = userMapper.selectById(1L);
// 2、修改用户信息
user.setName("kuangshen");
user.setEmail("24736743@qq.com");
// 3、执行更新操作
userMapper.updateById(user);
}
测试乐观锁失败!多线程下,表示线程1在执行操作的时候,突然被另外一个线程插队抢先执行了操作,并提交了的修改,这个时候线程1再提交的数据就无效。那么程序对于线程1来说,线程1提交的数据则不会成功。这个时候我们可以用自旋锁来多次尝试提交。
如果没有乐观锁就会覆盖插队线程的值! 就应该是改变的是由线程1指定修改的值。
@Test
public void testOptimisticLocker2(){
// 线程 1
User user = userMapper.selectById(1L);
user.setName("kuangshen111");
user.setEmail("24736743@qq.com");
// 模拟另外一个线程执行了插队操作
User user2 = userMapper.selectById(1L);
user2.setName("kuangshen222");
user2.setEmail("24736743@qq.com");
userMapper.updateById(user2);
// 自旋锁来多次尝试提交!
userMapper.updateById(user); // 如果没有乐观锁就会覆盖插队线程的值!
}
发现了名字修改成了“kuangshen222” 修改成线程2的值了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。