• MyBatis-Plus——实现乐观锁


    乐观锁——MyBatis-Plus实现

    针对于某一问题的解决方案,多线程或并发操作中产生的一些问题——丢失更新

    1. 主要适用场景:

    当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新·

    2. 乐观锁实现方式:

    取出记录时,获取当前version
    更新时,带上这个version
    执行更新时,set version = newVexsion where version = oldVersion
    如果version不对,就更新失败
    接下来介绍如何在Mybatis-Plus项目中,使用乐观锁:

    3. 乐观锁实现流程

    3.1 修改实体类属性

    1. 数据库中的字段version版本号字段
      在这里插入图片描述

    2. 创建实体类的对象属性——版本号操作属性上添加注释@Version

    User.java

    package com.guo.springboot.entity;
    
    import com.baomidou.mybatisplus.annotation.*;
    import lombok.Data;
    import java.util.Date;
    @Data
    @TableName("t_user")
    public class User {
        @TableId(type = IdType.AUTO)
        private int id;
        private String name;
        private String password;
        private String email;
        @TableField(fill = FieldFill.INSERT)
        private Date createTime;
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Date updateTime;
        @Version
        @TableField(fill = FieldFill.INSERT)   //添加元素时自动填充
        private Integer version;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    填充的内容设置

    MyMetaObjectHandler.java

    package com.guo.springboot.handler;
    import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    import org.apache.ibatis.reflection.MetaObject;
    import org.springframework.stereotype.Component;
    import java.util.Date;
    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
        //mp执行添加操作,这个方法执行
        @Override
        public void insertFill(MetaObject metaObject) {
            this.setFieldValByName("createTime",new Date(),metaObject);
            this.setFieldValByName("updateTime",new Date(),metaObject);
            this.setFieldValByName("version",1,metaObject);  //版本号创建的时候默认为1
        }
        //mp执行修改操作,这个方法执行
        @Override
        public void updateFill(MetaObject metaObject) {
            this.setFieldValByName("updateTime",new Date(),metaObject);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.2 注册乐观锁插件

    1. 创建配置文件
      创建包config,创建文件MybatisPlusConfig.java
      此时可以删除主类中的@MapperScan扫描注解
    2. 在MybatisPlusConfig中注册Bean
    package com.guo.springboot.config;
    
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
    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
    @Configuration
    @MapperScan("com.guo.springboot.mapper")
    public class MybatisPlusConfig {
        /**
         * 乐观锁插件
         */
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor(){
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
            return interceptor;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3.3 测试

    乐观锁每次修改数据后的版本号都会被修改,利用这个原理模拟测试一下数据修改后的版本号是否变化。

    1. 首先我们需要添加一条新的记录
    @Test
    public void insert(){
        User user = new User();
        user.setName("王五");
        user.setPassword("258369147");
        user.setEmail("848698119@qq.com");
        int insert = userMapper.insert(user);
        System.out.println(insert);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    2. 然后我们开始测试,先查询获取版本号然后做修改

    @Test
    public void OptimisticLocker(){
        //根据Id查询
        User user = userMapper.selectById(1);
        //修改
        user.setName("zhaoliu");
        userMapper.updateById(user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    修改成功!
    在这里插入图片描述

  • 相关阅读:
    Java操作文件Path 和 Paths 及Files类介绍
    数据库理论知识及相关发展方向
    Redis缓存雪崩、穿透、击穿,布隆过滤器,分布式锁详解
    详解SQL中Groupings Sets 语句的功能和底层实现逻辑
    Cadence OrCAD Capture 批量放置No Connect不连接的方法
    CSS-vmin&vmax单位
    基于JAVA开发使用IDEA兼容Eclipse的动漫视屏网站
    分布式websocket搭建方案
    C Primer Plus(6) 中文版 第10章 数组和指针 10.5 指针操作
    如何利用PCB创建PCB封装库
  • 原文地址:https://blog.csdn.net/qq_45896330/article/details/126810317