MyBatis-Plus 高级功能 —— 乐观锁插件

x33g5p2x  于2021-12-19 转载在 其他  
字(2.4k)|赞(0)|评价(0)|浏览(350)

一、引言

先来大概普及一下数据库锁的概念,以下解释来源网络部分

悲观锁:时刻保持着一个悲观的态度,对谁都不信任,总想着别人会修改我的数据,所以为了防止别人修改,每次都会上锁,防止别人修改自己的数据。导致的后果就是每次想要拿到数据就必须要等待拿到锁,是一个很浪费时间的过程,如果访问量很大就是悲观锁一个致命的缺陷。

乐观锁:乐观锁对这个世界都很乐观,对每个想要获取数据的操作,他都会认为大家不会对自己的数据进行修改,所以不会上锁,在访问量很大的时候相比于悲观锁,节省了很多时间,用户不需要等待获取锁。

如果说大量读取数据操作的时候,适合使用乐观锁。如果冲突较多建议使用悲观锁。

悲观锁实现方式是数据库采用加锁的机制,而乐观锁最常见的手动就是通过版本号,每次更新的时候需要判断版本号是否一致,如果一致才能正常更新,反之更新失败。

二、具体现实

步骤一:配置乐观锁插件,这个采用的springboot的配置方式。

/**
 * @Auther: IT贱男
 * @Date: 2019/6/12 15:06
 * @Description: MybatisPlus配置类
 */
@Configuration
public class MyBatisPlusConfig {

    /**
     * 乐观锁插件
     * @return
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }
}

步骤二:在实体类版本号的字段上加注解

/**
     * 版本号
     */
    @Version
    private Integer version;

步骤三:测试调用,从SQL语句得出MP会把设置进去的版本号当作更新条件,并且版本号+1更新进去。

@Test
    public void update(){
        // 更新对象
        User user = new User();
        user.setEmail("Test1111@email.com");
        user.setId(1L);

        // 需要把之前从数据库读出来的版本号设置进去
        user.setVersion(1);

        int update = userMapper.updateById(user);
        System.out.println(update);
    }
DEBUG==>  Preparing: UPDATE sys_user SET email=?, update_time=?, version=? WHERE id=? AND version=? AND is_delete='0' 
DEBUG==> Parameters: Test1111@email.com(String), 2019-09-19T16:00:38.149(LocalDateTime), 2(Integer), 1(Long), 1(Integer)
DEBUG<==    Updates: 1

三、使用注意细节

细节一:支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime

细节二:仅支持 updateById(id) 与 update(entity, wrapper) 方法

细节三:在 update(entity, wrapper) 方法下, wrapper 不能复用,这里小编给大家演示一下把,通过执行SQL语句看出,第一次更新是成功了,但是第二次更新失败了,在条件后面有两个版本号的条件。

@Test
    public void updateByMyWrapper() {
        // 条件构造器
        QueryWrapper<User> wrapper = Wrappers.query();
        wrapper.eq("name", "admin");

        // 对象1
        User user = new User();
        user.setEmail("Test@email.com");
        user.setVersion(2);

        userMapper.update(user,wrapper);

        // 对象2
        User user2 = new User();
        user2.setEmail("Test2@email.com");
        user2.setVersion(3);

        // 注意,注意,这里的wrapper,和上面是是用的同一个
        userMapper.update(user2,wrapper);

    }
updateFill......
DEBUG==>  Preparing: UPDATE sys_user SET email=?, update_time=?, version=? WHERE is_delete='0' AND name = ? AND version = ? 
DEBUG==> Parameters: Test@email.com(String), 2019-09-19T16:06:26.172(LocalDateTime), 3(Integer), admin(String), 2(Integer)
DEBUG<==    Updates: 1
updateFill......
DEBUG==>  Preparing: UPDATE sys_user SET email=?, update_time=?, version=? WHERE is_delete='0' AND name = ? AND version = ? AND version = ? 
DEBUG==> Parameters: Test2@email.com(String), 2019-09-19T16:06:26.238(LocalDateTime), 4(Integer), admin(String), 2(Integer), 3(Integer)
DEBUG<==    Updates: 0

相关文章