mybatisplus使用OptimisticLockerInnerInterceptor实现版本号乐观锁

Mybatis-Plus乐观锁 版本号不一致,修改失败的情况2.版本号一致,修改成功的情况修改成功后,会发现version自动增加了1,此时修改成功,下次修改版本号需要是2与数据库对应才可以修改成功,这就是乐观锁。 阅读详情
AI摘要

本文围绕Java项目中OptimisticLockerInnerInterceptor展开。先介绍乐观锁实现方式,即取记录时获取当前version,更新时带上该version,若version不对则更新失败。接着阐述创建项目的步骤,包括引入依赖、配置等。最后进行测试,展示修改时版本号的变化及乐观锁功能的实现。

目录

OptimisticLockerInnerInterceptor 介绍

创建项目

创建项目

引入依赖

创建数据表

application.yml配置

项目结构

配置乐观锁拦截器

创建实体类

创建mapper

创建service

创建返回包装类BaseResponse

创建UserController

测试

查询

修改

​编辑

修改后再查询 

再次按版本号0修改 

修改时不传入版本号


OptimisticLockerInnerInterceptor 介绍

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

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

创建项目

创建项目

引入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

创建数据表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`
(
    id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    version INT not NULL DEFAULT 0 COMMENT '版本年龄',
    PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

DELETE FROM user;
 
INSERT INTO user (id, name, age, email,version) VALUES
(1, 'Jone', 18, 'test1@baomidou.com',0),
(2, 'Jack', 20, 'test2@baomidou.com',0),
(3, 'Tom', 28, 'test3@baomidou.com',0),
(4, 'Sandy', 21, 'test4@baomidou.com',0),
(5, 'Billie', 24, 'test5@baomidou.com',0);

application.yml配置

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://XXX:63306/user
    username: 
    password: 

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

项目结构

配置乐观锁拦截器

package com.sky.mybatisversiondemo.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

创建实体类

version字段需要添加@Version注解表名是版本号字段
package com.sky.mybatisversiondemo.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;


@Data
public class User {
    /**
     * 主键ID
     */
    @TableId(value = "id")
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 邮箱
     */
    private String email;
    /**
     * 版本号
     */
    @Version
    private Integer version;

}

创建mapper

package com.sky.mybatisversiondemo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sky.mybatisversiondemo.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

创建service

这里利用了mybatisPlus的特性,提供了一些默认的查询。

UserService

package com.sky.mybatisversiondemo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.sky.mybatisversiondemo.entity.User;

public interface UserService extends IService<User> {
}
UserServiceImpl
package com.sky.mybatisversiondemo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.mybatisversiondemo.entity.User;
import com.sky.mybatisversiondemo.mapper.UserMapper;
import com.sky.mybatisversiondemo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

创建返回包装类BaseResponse

package com.sky.mybatisversiondemo.vo;

import lombok.Data;

@Data
public class BaseResponse<T> {
    protected int code = 0;
    protected String message = "成功";

    protected T data;

    public BaseResponse(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public static <T> BaseResponse of(T data) {
        BaseResponse<T> response = new BaseResponse();
        response.setData(data);
        return response;
    }
    public BaseResponse() {
    }
}

创建UserController

package com.sky.mybatisversiondemo.controller;

import com.sky.mybatisversiondemo.entity.User;
import com.sky.mybatisversiondemo.service.UserService;
import com.sky.mybatisversiondemo.vo.BaseResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/list")
    public BaseResponse list(){
        List<User> list = userService.list();
        return BaseResponse.of(list);
    }

    @GetMapping("/ById")
    public  BaseResponse ById(Integer id){
        User user = userService.getById(id);
        if (user != null){
            return BaseResponse.of(user);
        }else {
            return new BaseResponse(500,"fail");
        }
    }

    /**
     * 插入学生信息
     * @param user
     */
    @PostMapping("/insert")
    public BaseResponse insertInfo(@RequestBody User user){
        boolean save = userService.save(user);
        if (save){
            return BaseResponse.of(save);
        }
        return new BaseResponse(500,"fail");
    }

    /**
     * 根据id更新学生表信息
     * @param user
     */
    @PutMapping("/update")
    public BaseResponse updateById(@RequestBody User user){
        boolean save = userService.updateById(user);
        if (save){
            return BaseResponse.of(save);
        }
        return new BaseResponse(500,"fail");
    }

    /**
     * 根据id删除学生信息
     * @param id
     */
    @DeleteMapping("/delete")
    public BaseResponse deleteById(String id){
        boolean b = userService.removeById(id);
        if (b){
            return BaseResponse.of(b);
        }
        return new BaseResponse(500,"fail");
    }

}

测试

查询

修改

修改是自动增加版本号,并且会增加版本号的判断,只有版本号一致才能修改成功。

日志

==>  Preparing: UPDATE user SET name=?, age=?, email=?, version=? WHERE id=? AND version=?
==> Parameters: Jone(String), 18(Integer), test1@baomidou.com(String), 1(Integer), 1(Long), 0(Integer)
<==    Updates: 1

修改后再查询 

此时版本号增加到1

再次按版本号0修改 

修改失败,因为版本号已经增加到了1,实现了乐观锁功能。

如果开发中遇到这种因为乐观锁修改失败的,则可以直接报错,或者再次查询数据后重试。推荐直接报错,修改失败,请重试。

修改时不传入版本号

则可以直接修改成功 ,但是修改后版本号不会增加,不推荐不传入版本号的修改。

日志

==>  Preparing: UPDATE user SET name=?, age=?, email=? WHERE id=?
==> Parameters: Jone(String), 18(Integer), test1@baomidou.com(String), 1(Long)
<==    Updates: 1

【项目实战】使用MyBatis-Plus乐观锁插件功能 当要更新一条记录时,希望这条记录没有被别人更新,可以考虑使用MybatisPlus乐观锁插件功能来实现以上需求。 阅读详情

相关推荐

MyBatisPlus插件扩展_OptimisticLockerInterceptor乐观锁插件的使用示例代码

MyBatisPlus插件扩展_OptimisticLockerInterceptor乐观锁插件的使用示例代码

Mybatis-Plus入门系列(7)- MybatisPlus之乐观锁插件OptimisticLockerInnerInterceptor

乐观锁 并发控制:在计算机科学,特别是程序设计、操作系统、多重处理和数据库等领域,并发控制是确保及时纠正由并发操作导致的错误的一种机制。并发控制的基本单位是事务。数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。 乐观锁(Optimistic Locking):乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。乐观锁

记录知识、锤炼自我 5932

SMPTE ST 2110 概论(一)

SMPTE ST 2110 概论(一)前言ST 2110与ST 2022-6ST 2110-10:基本结构与时序ST 2110-20:未压缩的视频流后续 前言 这是一份我在实习期间制作的,关于SMPTE ST 2110的简单介绍。 这篇文章主要以梳理总结 SMPTE ST 2110 的概念为主,关于具体的内容,比如IP数据报的格式、RTP时间戳的具体代码内容等等,大家可以查阅 SMPTE ST 2...

Cidd0422的博客 2万+

springboot+mybatis-plus实现“乐观锁”

乐观锁 什么是乐观锁:是针对一些特定问题的解决方案,主要解决丢失更新问题 假如有一条数据同时被两个及以上的人进行修改,这个时候就会产生丢失更新问题。 譬如:小明想修改一条数据的money字段,他看到的money是500,他应该500太少想多加一点,改变成1000,但是小红也想改变money,她因为500太少想少加一点,改成600。小明的修改先发生,他们都是由500进行修改的,按理来说,小红应该是根据小明修改后的1000来修改成600,但是事实不是。这就叫丢失更新。 解决方案: 1悲观锁:某一个进行

weixin_56209516的博客 4459

02.1 知识图谱工具 Protege的下载安装与使用

Protege的下载安装与使用 本文是王昊奋老师《知识图谱》系列笔记第2.1篇。 文章目录Protege的下载安装与使用0 相关介绍0.0 Protege相关介绍0.1 Protégé的特点0.2 Protégé的用途1 Protege的下载1.1 准备工作:安装配置JAVA环境1.2 官网下载2 Protege的安装2.1 直接解压缩2.2 双击运行3 Protege的使用实例-创建类...

和而不流 7万+

uni-app - 修改默认端口,H5 项目控制台运行出来的 IP 地址的默认端口号(H5 项目运行后控制台,修改项目运行到内置浏览器默认 8080 端口号)

uni-app运行到H5修改默认端口号,uni-app如何修改默认端口,uni-app修改默认端口,uni-app本地运行修改调试已上线微信H5项目,请问在UNIAPP的H5运行调试时候的IP是否可以自己设置固定,uni-app开发环境,如何设置h5服务器的端口,uni-app如何修改默认端,uni-app修改默认端口,uni-app指定端口号,uni-app-修改H5项目控制台运行出来的IP地址的默认端口号(H5项目运行后控制台,修改项目运行到内置浏览器默认8080端口号)

🏆 前端领域优质创作者 9887

MyBatisPlus 之乐观锁04

MyBatisPlus 之乐观锁04 乐观锁 在面试过程中,我们经常会被问道乐观锁,悲观锁!这个其实非常简单! 乐观锁 : 故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题, 再次更新值测试 悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作! 我们这里主要讲解 乐观锁机制! 乐观锁实现方式: 取出记录时,获取当前 version 更新时,带上这个version 执行更新时, set version = ...

helloworld工程师的博客 407

运营商拼命封杀的PCDN到底是个啥?

最近一段时间,很多宽带用户发现自家的网速莫名其妙变慢了,甚至收到了运营商发来的“违规使用宽带”警告短信,严重的甚至直接被断网。很多人一头雾水:我交了钱办的宽带,自己买的插件或者京东云、网心云这些硬件赚点“电费”,怎么就成了运营商眼中的“过街老鼠”?今天,我们就把这层窗户纸捅破,深度剖析这个让互联网大厂省下几十亿、让运营商恨得牙痒痒、让用户夹在中间进退两难的技术黑话——。

网络技术联盟站 917

Mybatis-Plus乐观锁配置使用流程【OptimisticLockerInnerInterceptor】

Mybatis-Plus乐观锁配置使用流程【OptimisticLockerInnerInterceptor】

白大锅的博客,毕设WangLoveBai_999 2318

【2025最新版】Open3D 区域生长分割(python详细过程版)

点云区域生长分割算法的python详细过程版实现。博客长期更新,本文最新更新时间为:2025年3月23日。

点云侠的博客 9529

Python爬虫实战教程:如何高效爬取税务局通知通告

税务局发布的通知通告包含政策法规、办税指南、公告信息等,是纳税人、企业合规经营的重要参考。官网发布频率高,手动查看不便,自动爬取并保存,方便信息及时掌握及历史数据归档。本文以合法合规的方式示范,建议实际应用前确认目标网站允许爬取的范围和方式。建议使用pandas进行数据清洗,如去重、空值处理等。对于研究税务政策、进行大数据分析、搭建行业信息平台,爬取税务局通知通告信息尤为关键。公告列表以分页形式展现,包含标题、发布时间和详情页链接。进行政策趋势图、发布频率统计等可视化。爬取公开数据时,务必遵守网站的。

2201_76125261的博客 1781

【MyBatisPlus学习】乐观锁 OptimisticLockerInnerInterceptor插件 细解

文章目录乐观锁测试一下MP的乐观锁插件1、给数据库中增加version字段!2、我们实体类加对应的字段3、注册组件4、测试一下更多相关文章点这里 乐观锁 OptimisticLockerInnerInterceptor 乐观锁 : 故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题, 再次更新值测试 悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作! 我们这里主要讲解 乐观锁机制! 乐观锁实现方式: 当要更新一条记录的时候,希望这条记录没有被别

胡毛毛的博客 2092

十四种逻辑器件综合对比——《器件手册--逻辑器件》

逻辑器件是数字电路中最基本的逻辑单元,用于实现基本的逻辑运算,如与、或、非、异或等。逻辑门根据输入信号的组合产生相应的输出信号。与门:只有当所有输入信号都为高电平时,输出才为高电平。或门:只要有一个输入信号为高电平,输出就为高电平。非门:输出信号与输入信号相反。异或门:当两个输入信号不同时,输出为高电平;相同则输出为低电平。用于对输入信号进行反相操作,即将高电平转换为低电平,低电平转换为高电平。常用于信号的反相处理和逻辑电平的转换。

XU157303764的博客 2030

MybatisPlus乐观锁不起作用?

今天在使用mybatisplus3.4.1时候,使用乐观锁的过程中,我发现我的测试demo 使用updateByid的方法,version始终不会变化, 最后才发现,乐观锁的逻辑是这样的 1.首先通过id查出该数据 2.然后set方法进行修改 3.updateByid进行更新 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201227011200158.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5na.

weixin_45166406的博客 5072

YOLOv11改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进

如今各种网络模型更新迭代越来越快,计算机视觉相关的文章也越来越多,多到一些普通,通用的改进点无法达到发表的要求。本专栏正是解决这个问题!如何寻找创新点?为什么要使用这个模块?如何才能提升模型的精度?这是贯穿我们研究始终的问题。创新点在这个专栏中我已经整理好了,这已经省去了大部分时间,但是当我们使用这些新的模块去优化已有的模型,如何才能提升模型的精度,才是我们要达到的最终目标。当然我们可以使用传统的A+B+C的方法去堆积模块,然后是进行大量的实验去排列组合以实现最终的精度提升,这无可厚非。

Limiiiing的博客 6万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

mybatisplus乐观锁机制

啊

MMddhh_的博客 216

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

mybatisplus乐观锁最新

旧版本的乐观锁配置插件如下: @Configuration @MapperScan("com.zcy.mybatisplus.mapper") @EnableTransactionManagement public class MybatiPlusConfig { @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor(){ return new OptimisticLockerInterc

z19799100的博客 534

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

悲观锁、乐观锁、mybatis-plus实现乐观锁

具体步骤如下:​ 1.创建自定义拦截器类首先,你需要创建一个类来实现 MyBatis-Plus 的接口。这个接口定义了一些方法,允许你在 SQL 执行的不同阶段插入自定义逻辑。// 你的自定义逻辑将在这里实现 }// 你的自定义逻辑将在这里实现 }// 你的自定义逻辑将在这里实现 }// 你的自定义逻辑将在这里实现 }// 你的自定义逻辑将在这里实现 }SqlInfo;import com// 你的自定义逻辑将在这里实现 }

weixin_44846436的博客 705

记录:MP注册乐观锁和分页时 OptimisticLockerInterceptor 已弃用

个人公众号: 编程之外 Hexo博客: http://vogos.cn/ OptimisticLockerInterceptor 已弃用   最近写项目用到了 MyBatis Plus 在注册乐观锁时发现 OptimisticLockerInterceptor 已弃用,虽然还可以正常使用,但看着那条删除线实在影响代码美观,说不定哪天 OptimisticLockerInterceptor 就不可以用了   还没研究官方为什么要弃用它,就像JDK8之后 Date 的很多方法也都弃用了,主要是因为 Da.

遇见0和1的博客 6108

mybatis-plus实现乐观锁

mybatis-plus官方文档:https://mp.baomidou.com/guide/interceptor-optimistic-locker.html#optimisticlockerinnerinterceptor 当要更新一条记录的时候,希望这条记录没有被别人更新。他是用来保证在多线程操作下的安全的。 乐观锁实现方式(OptimisticLockerInnerInterceptor): 取出记录时获取当前按version 更新时带上这个version 执行更新时, set version

weixin_43919497的博客 554

mybatis-plus 乐观锁

mybatis-plus 乐观锁

不是七七子的博客 1596

mybatis plus乐观锁

mybatis plus中的OptimisticLockerInnerInterceptor与OptimisticLockerInterceptor 新版的mybatis plus中,OptimisticLockerInnerInterceptor已经被弃用,改为OptimisticLockerInterceptor 旧版的乐观锁代码: package com.nanyuan.mybatisplus.config; import com.baomidou.mybatisplus.exte

loliDapao的博客 999

关于MybatisPlus乐观锁的MyBatisSystemException

在SpringBoot整合MybatisPlus的乐观锁版本问题的时候,会碰到的报错。 SpringBoot 2.5.7 +MybatisPlus 3.4.1 应该是3.4.1版本把原来的方法过时处理了,导致在容器找不到Bean。 改为下面就可以正常使用: @Bean public MybatisPlusInterceptor optimisticLockerInnerInterceptor(){ MybatisPlusInterceptor interceptor = ne.

m0_60744925的博客 463

[Mybatis-Plus笔记] MybatisPlus-06-乐观锁

user1 进行更新后,version 值也自动被改变,所以 user1 可以继续进行更新操作,但 user2 想要更新就必须再进行一次查询来读取新的数据。可见更新时的 WHERE 语句中自动加入了对 version 的判断,如果数据库中的 version 值与当前 version 不相等,则不会更新。乐观锁指,对于同一个数据,某一个事务正在进行时,不会阻止其它事务的操作,但在更新操作时会判断此前是否有其它事务进行了更新。换句话讲,如果当前事务读取的数据是过时的,那么此事务不被允许进行更新操作。

Cey_Tao的博客 953

OptimisticLockerInnerInterceptor与OptimisticLockerInterceptor

OptimisticLockerInterceptor 在新版本的MP中已弃用,但仍然能用,下班是两种注册方式: @Configuration @MapperScan("com.renxws.mpdemo01.mapper") public class MpConfig { // 注册乐观锁插件(新版:3.4.0) @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusIn.

2008的专栏 1872

MybatisPlus乐观锁

MybatisPlus乐观锁

qixiang_chen的博客 61
上一篇: redis缓存和数据库通过延迟双删除实现数据一致性
下一篇: python爬取网页接口数据,以yearning为例
bxp1321
博客等级 码龄17年 146粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值