SpringBoot + MyBatisPlus中乐观锁的实现 (精简demo)

乐观锁加注解@Version后不需要手动进行加1操作。乐观锁是一种用于解决并发冲突的机制,在数据库中用于保护数据的一致性。@Version注解是MyBatisPlus框架中的乐观锁注解,它会在更新数据时自动检查版本号是否一致,如果一致则进行更新操作,如果不一致则表示数据已被其他线程修改过,更新操作会失败。@Version注解会自动对版本号进行加1操作,所以在使用乐观锁时不需要手动进行加1操作。当进行更新操作时,MyBatisPlus会自动更新版本号,并将更新后的版本号与更新条件一起发送给数据库,如果版本号在更新过程中发生变化,则说明数据已被其他线程修改,更新操作会失败。因此,使用乐观锁加注解@Version后,可以简化代码,并且可以保证数据的一致性

使用场景: 当要更新一条数据时,希望这条数据没有被别人更新,也就是说实现线程安全的数据更新

1. 数据库新增version字段, int类型, 默认值为0

2. 引入依赖
<!--MyBatisPlus 拦截器-->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version>
</dependency>

3. springboot启动类中新增bean
/*** 支持拦截器乐观锁** @return*/@Beanpublic MybatisPlusInterceptor optimisticLockerInterceptor(){MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
 

4. 实体类 version字段贴上注解 @Version

@Version
private Long version;

5. sql更新语句 (@Version注解会自动对版本号进行加1操作,所以在使用乐观锁时不需要手动进行加1操作)
// 没加@Version注解sql
update wx_dept set name=#{name}, sn=#{sn}, version=#{version}+1 where id=#{id} and version=#{version}// 加了@Version注解sql
update wx_dept set name=#{name}, sn=#{sn}, version=#{version} where id=#{id} and version=#{version}

6. service (乐观锁操作步骤: 每次操作前都是先查询、替换、最后更新, 否则乐观锁无效)
    /*** 修改部门* * @param wxDept 部门* @return 结果*/@Overridepublic AjaxResult updateWxDept(WxDept wxDept) {// 乐观锁操作步骤: 每次操作前都是先查询、替换、最后更新, 否则乐观锁无效// 1. 先查询WxDept dept = wxDeptMapper.selectWxDeptById(wxDept.getId());log.info("查询出来的数据: {}", dept);// 2. 替换dept.setName("小卖铺");dept.setSn("sell");// 3. 最后更新int i = wxDeptMapper.updateWxDept(dept);if (i > 0) {return AjaxResult.success("乐观锁更新成功");} else {return AjaxResult.error("乐观锁更新失败");}}

7. 测试
7.1 查询出id是1的数据, 并修改数据 name=小卖铺, sn=sell

查询出来的数据: com.ruoyi.ruoyiwx.dept.domain.WxDept@861f795[id=1name=开发部sn=devversion=0
]

7.2   假设7.1还没更新时, 就有其它线程修改了id为1的数据, 版本号version=1

7.3   上面7.1执行update更新时就会失败, 因为版本号version=1, 不是刚查询出来的version=0 

{"msg": "乐观锁更新失败","code": 500
}
总结: 
1. 每次去拿数据的时候都会认为别人不会修改数据, 所以不会上锁
2. 但是在更新的时候会判断在此期间有没有人去更新过这个数据, 可以使用版本号version

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/100571.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何选择 DCDC 降压型开关电源的电感

选择合适的电感是开关电源电路设计的关键之一。本文将帮助您理解电感值和电路性能之间的关系。 降压转换器&#xff08;buck converter&#xff09;&#xff0c;也称为降压转换器(step-down converter)&#xff0c;是一种开关模式稳压器&#xff08;voltage regulator&#xf…

220V转5V芯片三脚芯片-AH8652

220V转5V芯片三脚芯片是一种非常常见的电源管理芯片&#xff0c;它通常被用于将高压交流输入转为稳定的直流5V输出。芯片型号AH8652是一款支持交流40V-265V输入范围的芯片&#xff0c;采用了SOT23-3三脚封装。该芯片内部集成了650V高压MOS管&#xff0c;能够稳定地将输入电压转…

R语言APSIM模型进阶应用与参数优化、批量模拟实践技术

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

vite 项目搭建

1. 创建 vite 项目 npm create vite@latest 2. 安装sass/less ( 一般我使用sass ) cnpm add -D sasscnpm add -D less 3. 自动导入 两个插件 使用之后,不用导入vue中hook reactive ref cnpm install -D unplugin-vue-components unplugin-auto-import 在 vite.config.…

记录一个用C#实现的windows计时执行任务的服务

记录一个用C#实现的windows计时执行任务的服务 这个服务实现的功能是每天下午六点统计一次指定路径的文件夹大小 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO; using Syst…

【实战】十一、看板页面及任务组页面开发(三) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二十五)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…

基于Spring Boot的智慧团支部建设网站的设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的智慧团支部建设网站的设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java sp…

stm32的命令规则

stm32型号的说明&#xff1a;以STM32F103RBT6这个型号的芯片为例&#xff0c;该型号的组成为7个部分&#xff0c;其命名规则如下&#xff1a;

生成式AI和大语言模型 Generative AI LLMs

在“使用大型语言模型(LLMs)的生成性AI”中&#xff0c;您将学习生成性AI的基本工作原理&#xff0c;以及如何在实际应用中部署它。 通过参加这门课程&#xff0c;您将学会&#xff1a; 深入了解生成性AI&#xff0c;描述基于LLM的典型生成性AI生命周期中的关键步骤&#xff…

OpenAI首席执行官谈马斯克退出的影响;关于 Stable Diffusion 扩展功能的内容总结

&#x1f989; AI新闻 &#x1f680; OpenAI首席执行官谈马斯克退出的影响 摘要&#xff1a;OpenAI首席执行官萨姆奥特曼在接受采访时表示&#xff0c;埃隆马斯克退出OpenAI给公司带来了巨大震惊&#xff0c;导致奥特曼不得不重新调整生活和时间安排以确保足够资金。OpenAI是…

hive中get_json_object函数不支持解析json中文key

问题 今天在 Hive 中 get_json_object 函数解析 json 串的时候&#xff0c;发现函数不支持解析 json 中文 key。 例如&#xff1a; select get_json_object({ "姓名":"张三" , "年龄":"18" }, $.姓名);我们希望的结果是得到姓名对应…

七夕节日表白:七大网页风格与其适用人群

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

SVM详解

公式太多了&#xff0c;就用图片用笔记呈现&#xff0c;SVM虽然算法本质一目了然&#xff0c;但其中用到的数学推导还是挺多的&#xff0c;其中拉格朗日约束关于α>0这块证明我看了很长时间&#xff0c;到底是因为悟性不够。对偶问题也是&#xff0c;用了一个简单的例子才明…

文心一言 VS 讯飞星火 VS chatgpt (79)-- 算法导论7.4 4题

四、请用go语言&#xff0c;证明:RANDOMIZED-QUICKSORT 期望运行时间是 Ω(nlgn)。 文心一言&#xff1a; 首先&#xff0c;为了证明RANDOMIZED-QUICKSORT的期望运行时间是Ω(nlg n)&#xff0c;我们需要证明在最坏的情况下&#xff0c;该算法的运行时间是O(nlg n)。然后&…

1.0的星火2.0必将燎原——图文声影PPT全测试

一、前言 大家好&#xff0c;勇哥又来分享AI模型了&#xff0c;前几天讯飞发布的星火大模型2.0迅速的进入了我们圈子里&#xff0c;为了有更多更好的模型分享给大家&#xff0c;分享星火大模型2.0是必须做的&#xff0c;我做一个传递着&#xff0c;希望大家也星火相传啊。 我…

解决执行 spark.sql 时版本不兼容的一种方式

场景描述 hive 数据表的导入导出功能部分代码如下所示&#xff0c;使用 assemble 将 Java 程序和 spark 相关依赖一起打成 jar 包&#xff0c;最后 spark-submit 提交 jar 到集群执行。 public class SparkHiveApplication {public static void main(String[] args){long sta…

操作系统——shell编程

文章目录 shell入门什么是 Shell&#xff1f;Shell 编程的 Hello World Shell 变量Shell 编程中的变量介绍Shell 字符串入门Shell 字符串常见操作Shell 数组 Shell 基本运算符算数运算符关系运算符逻辑运算符布尔运算符字符串运算符文件相关运算符 shell流程控制if 条件语句for…

市面上那里有稳定L2股票行情数据接口?

随着市场的发展和技术的进步&#xff0c;level2股票行情数据接口已经成为股票交易软件的标准配置之一。虽然这些券商软件的功能在很大程度上相似&#xff0c;但它们仍然有自己的特点和优势。 例如&#xff1a;通过股票交易所以其专业的研究报告和丰富的信息服务而受到广泛关注&…

Shell编程基础02

0目录 1.case语法 2.grep 3.sed 4.awk 5.linux安装mysql 1.case语法 创建一个txt文档 执行 查询用户名 case 用法 写一个计算器脚本 加入函数 补充查看进程命名 2.find grep命令 Find 查询当前目录下 以sh结尾的文件 Grep 查询义开头的 或者加入正则表达…

Java --- 二维数组

一、二维数组的定义 public class TwoArrayTest {public static void main(String[] args) {//二维数组声明与初始化//方式1&#xff1a;静态初始化int[][] arr new int[][]{{1,2,3},{1,2,3},{1,2,3}};//方式2&#xff1a;动态初始化int[][] arr2 new int[3][3];arr2[0][1] …