美文网首页
SpringBoot之【mybatisplus】乐观锁

SpringBoot之【mybatisplus】乐观锁

作者: MR_jw | 来源:发表于2019-12-31 16:08 被阅读0次

    1、概述


    应用场景:当要更新一条记录的时候,希望这条记录没有被别人更新

    悲观锁乐观锁区别:

    • 悲观锁: 悲观的认为我要修改的数据一定会被他人修改,如果我要修改数据,我就会给数据上锁,别人都不能去修改,我修改完之后别人才可以修改
    • 乐观锁:乐观的认为我修改的数据别人别人不会去改,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制(version)和CAS算法实现

    两种锁适用场景

    乐观锁适用于写少读多的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量


    悲观锁适用于写多读少,多写,一般会经常产生冲突,这就会导致上层应用会不断的进行重试,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

    阿里巴巴建议以冲突概率20%这个数值作为分界线来决定使用乐观锁和悲观锁,
    虽然说这个数值不是绝对的,但是作为阿里巴巴各个大佬总结出来的也是一个很好的参考。
    

    2、实现(两步)

    2.1 插件配置
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
    
    2.2 注解实体字段 @Version 必须要!

    实体类User添加 字段version
    <font color='red'>同时数据库记得添加version字段</font>

    public class User implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        /**
         * 主键ID
         */
        @TableId(value = "id", type = IdType.AUTO)
        private Integer id=null;
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private Integer age;
    
        /**
         * 邮箱
         */
        private String email;
    
        @Version
        private Integer version;
    
    
    }
    

    UserController
    业务:id为n的一行数据的年龄age +1的操作

    @RestController
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        private IUserService service;
            @RequestMapping("/lock")
        public void lock(Integer id){
                User byId = service.getById(1);
                User user = new User();
                user.setId(1);
                user.setAge(byId.getAge()+1);
                user.setVersion(byId.getVersion());
                boolean b = service.updateById(user);
               if (b){
                   System.out.println("-----------+++++++++++年龄增加成功++++++++++++++++++++++++++++--");
               }else{
                   System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试");
               }
            }
    }
    

    测试类:
    模拟开启50个线程模拟同时对id为n的数据操作

    @Autowired
        private TestRestTemplate testRestTemplate;
        @Test
            //测试乐观锁
        void testLock() {
    
            String url = "http://localhost:8080/user/lock";
            for (int i = 0; i <50 ; i++) {
                new Thread(()->{
    
                    MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
                    params.add("id","1");
                    String result = testRestTemplate.postForObject(url, params, String.class);
    
                }).start();
            }
        }
    

    测试结果:
    数据库增加的年龄对应, 没有多+也没有少+

    -----------+++++++++++年龄增加成功++++++++++++++++++++++++++++++++++++----------------------------------------
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    -----------+++++++++++年龄增加成功++++++++++++++++++++++++++++++++++++----------------------------------------
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    -----------+++++++++++年龄增加成功++++++++++++++++++++++++++++++++++++----------------------------------------
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    -----------+++++++++++年龄增加成功++++++++++++++++++++++++++++++++++++----------------------------------------
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$年龄增加失败,请重试
    

    代码地址:https://github.com/jw-star/mybatis-plusDemo/tree/master/mybatisplusdemo
    相关文章:
    SpringBoot之【mybatisplus】快速上手
    SpringBoot之【mybatisplus】代码生成器
    SpringBoot之【mybatisplus】分页插件、条件查询、sql打印开启
    SpringBoot之【mybatisplus】乐观锁

    相关文章

      网友评论

          本文标题:SpringBoot之【mybatisplus】乐观锁

          本文链接:https://www.haomeiwen.com/subject/uyzboctx.html