MyBatis-Plus——乐观锁处理

729 阅读2分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战

乐观锁和悲观锁

乐观锁:当要对数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。悲观锁,具有强烈的独占和排他特性。它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度。因此,在整个数据处理过程中,将数据处于锁定状态。

悲观锁:乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果冲突,则返回给用户异常信息,让用户决定如何去做。乐观锁适用于读多写少的场景,这样可以提高程序的吞吐量。

乐观锁实现方式:

  • 取出记录时,获取当前 version

  • 更新时,带上这个 version

  • 执行更新时, set version = newVersion where version = oldVersion

  • 如果 version 不对,就更新失败

测试乐观锁插件

1、在表里新增 version 字段

在这里插入图片描述

2、实体类添加属性,加上@version 注解

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    @TableField(fill = FieldFill.INSERT) //插入时更新字段
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)//插入和修改时更新字段
    private Date updateTime;

    @Version //乐观锁注解
    private Integer version;
}

3、编写配置文件,配置乐观锁插件

@Configuration
@MapperScan("com.haoming.mapper")
@EnableTransactionManagement
public class MyBatisPlusConfig {
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

4、测试

测试版本号变化:

   @Test
    void test1(){
        User user = userMapper.selectById(11L);
        //修改数据
        user.setName("wanli");
        user.setAge(100);
        //执行
        userMapper.updateById(user);
    }

经过上面的修改,版本号由默认的1变成了2

在这里插入图片描述

多用户下进行测试:

@Test
void test1(){
    User user = userMapper.selectById(11L);
    user.setName("wanli");
    user.setAge(100);

    //user1在user执行的时候插队了
    User user1 = userMapper.selectById(11L);
    user1.setName("shenming");
    user1.setAge(10);
    userMapper.updateById(user1);
}

查看结果:

在这里插入图片描述

最后显示的是user1的结果,说明user的结果被user1覆盖了。如果不是乐观锁,而是悲观锁的话,user对象执行的结果时候就不会被user1插队,user的结果也就不会被user1覆盖。