zoukankan      html  css  js  c++  java
  • 【Mybatis-Plus进阶学习(四)】乐观锁

    什么时乐观锁?
    第一步,先取出记录,获取当前version;第二步,当更新时,带上这个version;第三步:版本正确更新成功,错误更新失败。

    示例:
    update user set name = '向南天,version =3 where id = 1094592041087729777 and version = 2

    乐观锁和悲观锁是两种思想,用于解决并发场景下的数据竞争问题。

    • 乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。
    • 悲观锁:悲观锁在操作数据时比较悲观,认为别人会同时修改数据。因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。

    来自【BAT面试题系列】面试官:你了解乐观锁和悲观锁吗?

    所以悲观锁用于多写的情况,防止出现同时修改的问题,而乐观锁用于多读的情况,不上锁可以增加资源的利用。

    乐观锁的简单使用

    第一步:配置乐观锁拦截器

        @Bean
        public OptimisticLockerInterceptor optimisticLockerInterceptor() {
            return new OptimisticLockerInterceptor();
        }
    

    第二步:在更新前先查询版本号,之后在更新时带上版本号作为查询判断条件

        @Test
        public void modifyById() {
            //查出原来的Version
            int version = userMapper.selectById(1094592041087729666L).getVersion();
            //修改
            User user = new User();
            user.setId(1094592041087729666L);
            user.setEmail("wsd@163.com");
            //设置版本号
            user.setVersion(version);
            int row = userMapper.updateById(user);
            System.out.println("影响的行数:" + row);
        }
    

    结果如下

    MP会自动将设置的版本号作为查询条件连接在SQL语句后面,然后将版本号+1再重新设置进数据库。

    注意事项

    这是官方就乐观锁给出的说明

    关于官方提示的最后一点,请看:

            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name", "刘红雨");
            //查出原来的Version
            int version = userMapper.selectById(1094592041087729666L).getVersion();
            //修改
            User user = new User();
            user.setEmail("wsd1@163.com");
            //设置版本号
            user.setVersion(version);
            int row = userMapper.update(user,queryWrapper);
            System.out.println("影响的行数:" + row);
    
    
            int version2 = userMapper.selectById(1094592041087729666L).getVersion();
            //修改
            User user2 = new User();
            user2.setEmail("wsd1@163.com");
            //设置版本号
            user2.setVersion(version2);
            //复用Query
            int row2 = userMapper.update(user2,queryWrapper);
            System.out.println("影响的行数:" + row2);
    

    两个同样的修改,但是使用了同一个Wrapper,接下来,我们看看结果

    可以看出第一个更新十分正常,但是第二个更新的时候条件出现了两个Version,这就是为什么在 update(entity, wrapper)方法下, wrapper 不能复用的原因。

  • 相关阅读:
    hibernate4.3.10使用注解映射方式样例
    eclipse ssh连接sqlserver express
    window2012 64bit 安装sqlserver2012 64bit调用excel的驱动安装
    SharpZipLib要支持unicode的文件名称
    搜索数据库中的内容
    AIX 添加开机启动项
    oracle 分区表和分区索引
    oracle 临时表学习
    oracle sys sysman system 介绍
    oracle to_date函数(转载)
  • 原文地址:https://www.cnblogs.com/zllk/p/14239765.html
Copyright © 2011-2022 走看看