乐观锁:每次不加锁而是假设没有冲突而去完成某项 *** 作,如果失败就重试,直到成功为止
悲观锁:synchronized是独占锁即悲观锁,会导致其他所有需要锁的线程挂起,等待有锁的线程释放锁
乐观锁实现方式:
-
取出记录时,获取当前version
-
更新时,带上这个version
-
执行更新时,set version = newVersion where version = oldVersion
-
如果version不对,就更新失败
#乐观锁:先查询,获得版本号 -- A update user set name = "wsk",version = version+1 where id = 1 and version = 1 -- B (B线程抢先完成,此时version=2,会导致A线程修改失败!) update user set name = "wsk",version = version+1 where id = 1 and version = 1
测试一下Mybatis-Plus乐观锁插件
1、给数据库中增加version字段
2、实体类加对应的字段
@Version//乐观锁version注解 private Integer version;
3、注册组件
//扫描mapper文件夹 @MapperScan("com.huang.mapper")//交给mybatis做的,可以让这个配置类做扫描,将主类注解删除 @EnableTransactionManagement//自动管理事务 @Configuration//配置类 public class MyBatisPlusConfig { //注册乐观锁插件 @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor(){ return new OptimisticLockerInterceptor(); } }
4、测试
- 成功
//测试乐观锁成功 public void testOpimisticLocker(){ //1、查询用户信息 User user = userMapper.selectById(1L); //2、修改用户信息 user.setAge(18); user.setEmail("1024955508@qq.com"); //3、执行更新 *** 作 userMapper.updateById(user); }
-
模拟多线程失败场景
//测试乐观锁失败 @Test//测试乐观锁失败 多线程下 public void testOptimisticLocker2(){ //线程1 User user1 = userMapper.selectById(1L); user1.setName("乐观成功"); //模拟另外一个线程执行了插队 *** 作 User user2 = userMapper.selectById(1L); user2.setName("插队"); userMapper.updateById(user2); //自旋锁来多次尝试提交! userMapper.updateById(user1);//如果没有乐观锁就会覆盖插队线程的值 }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)