看狂神视频然后总结笔记,为以后自己复习用,如有错误,可在评论中指出,一起成长。
乐观锁与悲观锁
乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁。
CAS属于乐观锁。
悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。
synchronized、Lock属于悲观锁。
Lock有三种实现类:ReentrantLock、ReadLock(读锁)和WriteLock(写锁)。
乐观锁(OptimisticLockerInnerInterceptor)
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
引入MyBatis-Puls的乐观锁插件
1、给数据库中增加version字段
2、实体类添加对应字段和注解(@Version)
@Version //乐观锁Version注解
private Integer version;
3、注册组件
@Configuration
@EnableTransactionManagement
@MapperScan("com.lzy.mapper")//扫描mapper包,很重要,启动类的扫描注解可以写到这
public class MybatisPlusConfig {
//注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
4、测试
//乐观锁成功情况
@Test
void testOptimisticLocker(){
//1、查询用户信息
User user = userMapper.selectById(1l);
//2、修改用户信息
user.setName("xiaodidi");
//3、执行更新
userMapper.updateById(user);
}
//乐观锁失败情况,多线程
@Test
void testOptimisticLocker2(){
//线程1
User user = userMapper.selectById(1l);
user.setName("xiaodidi");
//模拟另一个线程2插队操作
User user1 = userMapper.selectById(1l);
user1.setName("xiaodidi2");
userMapper.updateById(user1);
//3、执行更新,失败,version的不已经被线程2修改了
userMapper.updateById(user); //如果没有乐观锁就会覆盖user1的值
}