mybatisPlus-乐观锁处理

承接:mybatisPlus-自动填充

乐观锁:顾名思义十分乐观,它总是认为不会出现问题,无论干什么都不去上锁,如果出现了问题,再次更新值测试.

悲观锁:顾名思义十分悲观,它总是认为会出现问题,无论干什么都会上锁,再去操作.

1 乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果 version 不对,就更新失败

2 user表中增加字段

3 编写user实体类对应的属性

src/main/java/com/lv/mybatis_plus/pojo/User.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;

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

    //字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

4 编写配置类

新建一个config包,并在该包下新建MybatisPlusConfig.java,注意这里将之前在主启动类上的扫描mapper文件夹的@MapperScan注解转移到这个配置类上了

src/main/java/com/lv/mybatis_plus/config/MybatisPlusConfig.java

package com.lv.mybatis_plus.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@MapperScan("com.lv.mybatis_plus.mapper") //扫描mapper文件夹
@Configuration //配置类
public class MybatisPlusConfig {
    //注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

5 编写乐观锁成功的测试方法,并运行

//测试乐观锁成功
@Test
public void testOptimisticLocker(){
    //1.查询用户信息
    User user = userMapper.selectById(1L);
    //2.修改用户信息
    user.setName("汽水");
    user.setEmail("qishui@qq.com");
    //3.执行更新操作
    userMapper.updateById(user);
}

6 查看数据库user表

version字段变成了2

7 编写乐观锁失败的测试方法,并运行

//测试乐观锁失败
@Test
public void testOptimisticLocker2(){
    //线程一
    User user = userMapper.selectById(1L);
    user.setName("汽水");
    user.setEmail("qishui@qq.com");
    //模拟另一个线程执行了插队操作
    User user2 = userMapper.selectById(1L);
    user2.setName("可乐");
    user2.setEmail("kele@qq.com");

    userMapper.updateById(user2);
    //自旋锁来多次尝试提交!
    userMapper.updateById(user);//如果没有乐观锁就会覆盖插队线程的值!
}

8 查看控制台日志

注意自动生成了的sql语句中 version字段的位置,version和主键id都是判断条件

9 查看数据库user表

修改为user2的值了,因为先执行了修改user2,version发生了改变,变成了3,所以第二条sql也就是修改为user值的那一条就没有生效了

posted @ 2022-03-31 13:08  从0开始丿  阅读(683)  评论(0编辑  收藏  举报