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

news2025/1/20 18:38:16

目录

定义

场景

乐观锁与悲观锁

模拟修改冲突数据库中增加商品表

乐观锁实现

 悲观锁


定义

1)乐观锁

首先来看乐观锁,顾名思义,乐观锁就是持比较乐观态度的锁。就是在操作数据时非常乐观,认为别的线程不会同时修改数据,所以不会上锁,但是在更新的时候会判断在此期间别的线程有没有更新过这个数据。

2)悲观锁

反之,悲观锁就是持悲观态度的锁。就在操作数据时比较悲观,每次去拿数据的时候认为别的线程也会同时修改数据,所以每次在拿数据的时候都会上锁,这样别的线程想拿到这个数据就会阻塞直到它拿到锁。

场景


一件二手苹果手机,成本价是800元,售价是1000元。老板先是通知小李,说你去把商品价格增加500元。小李正在玩游戏,耽搁了一个小时。正好一个小时后,老板觉得商品价格增加到1500元,价格太高,可能会影响销量。又通知小王,你把商品价格降低300元。
此时,小李和小王同时操作商品后台系统。小李操作的时候,系统先取出商品价格1000元;小王也在操作,取出的商品价格也是1000元。小李将价格加了500元,并将1000+500=1500元存入了数据库;小王将商品减了300元,并将1000-300=700元存入了数据库。是的,如果没有锁,小李的操作就完全被小王的覆盖了。
现在商品价格是700元,比成本价低100元。几分钟后,这个商品很快出售了1千多件商品,老板亏10万多。

乐观锁与悲观锁


上面的故事,如果是乐观锁,小王保存价格前,会检查下价格是否被人修改过了。如果被修改过了,则重新取出的被修改后的价格,1500元,这样他会将1200元存入数据库。
如果是悲观锁,小李取出数据后,小王只能等小李操作完之后,才能对价格进行操作,也会保证最终的价格是1200元。


模拟修改冲突数据库中增加商品表

准备一张商品表

存入苹果手机

 

这里以第二条数据作为例子举例

后台java模拟二人同时拿到数据并进行修改

运行测试:

 

 可以看到最后测试结果是老板拿到的结果是700,比成本价还低了100,这样的场景肯定是不符合实际的业务需求的

乐观锁实现

数据库中添加version字段

取出记录时 获取当前信息的version

select id,商品名,商品价格,version from 商品表 where id =2

更新数据时 version+1 如果where语句中的version版本号不对 则更新失败

update 商品 set 价格 = 新的价格,`version`=`version`+1 where id = 2 and `version` = 1

 

 mybaits-plus相关调整

后台中表相对的实例对象添加对应version字段 并添加@Verison注解

 添加mybatis-plus插件

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //添加乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

注意把刚才的价格重新改回1000再重新测试:

注意看此时的更新sql, 小李的更新sql+500成功了,小王的-300失败了,所以此时老板查到的结果应该是1500

 此时可以看到,两者的修改并没有发生冲突,但是也出现了新的问题,就是小李的修改成功了,但是小王的却修改失败了,遇到这种情况的话小王可能要面临卷铺盖的风险啊,为了不让小王卷铺盖,我们这里可以为小王添加一个修改重试的功能

 

 再次测试下,注意要把价格重新改回1000哦:

此时结果显示老板查询到的就已经是他想要的结果1200了

 悲观锁

悲观锁解决方案非常简单 直接在操作sql中添加 for update语句即可

select id,商品名,商品价格,version from 商品表 where id =2 for update

使用 for update操作 可以认为是给每次操作都加上表级别的悲观锁 在事务没结束前 其他事务必须等待加锁的事务提交后才可以

 注意:并发环境下都不建议使用悲观锁,因为悲观锁容易锁表,导致事务等待,性能低下。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

红旅在线语料库网站 开发笔记

桂林红色旅游资源在线语料库网站 (Guilin Red Culture Corpus)提供双语文本检索和分享功能。供英语、翻译相关专业的爱好者,学生和老师学习使用。 该网站是对BiCorpus开源项目的二次开发(已获得原作者授权)。 项目仓库:RedCorpu…

小米miui14更新公测

一人内测,全员公测,懂得都懂[滑稽] 必应搜索醉里博客http://202271.xyz?miui 1月份有一部分机型就要公测了,相关用户愿意等的可以再等等。 本篇介绍最简单粗暴的替换法,不管你刷没刷过机都可以用这个方法偷渡MIUI14 ★★★评论…

区间预测 | MATLAB实现QRCNN-GRU卷积门控循环单元分位数回归时间序列区间预测

区间预测 | MATLAB实现QRCNN-GRU卷积门控循环单元分位数回归时间序列区间预测 目录 区间预测 | MATLAB实现QRCNN-GRU卷积门控循环单元分位数回归时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于QRCNN-GRU分位数回归卷积门控循环…

可靠性设计:元器件、零部件、原材料的选择与控制

通常,一个产品由各种基础产品(包括各种元器件、零部件等)构成。由于元器件、零部件的数量、品种众多,所以他们的性能、可靠性、费用等参数对整个系统性能、可靠性、寿命周期费用等的影响极大。 原材料则是各种基础产品的基本功能赖以实现的基础&#xf…

储氢合金/金属氢化物床层有效导热系数的数学模型

最近看到一篇有关“储氢合金/金属氢化物床层有效导热系数的数学模型”的论文,文章DOI:10.1016/j.energy.2023.127085,文章提到的数学物理模型还算好理解一些,特意分享给各位感兴趣的大佬。 一、物理模型简图和假设 文章里&#xf…

数模之Apriori关联算法

一、问题 中医证型的关联规则挖掘 背景: 中医药治疗乳腺癌有着广泛的适应证和独特的优势。从整体出发,调整机体气血、阴阳、脏腑功能的平衡,根据不同的临床证候进行辨证论治。确定“先证而治”的方向:即后续证侯尚未出现之前&am…

前后端分离博客】学习笔记04 --- 文件上传-策略模式

一、思路 我们定义一个接口(就比如接下来要实现的文件上传接口)我们定义所需要实现的策略实现类 A、B、C、D(也就是项目中所使用的四种策略阿里云Oss上传、腾讯云Cos上传、七牛云Kodo上传、本地上传)我们通过策略上下文来调用策略…

基础IO(一)

基础IO(一) 1.文件基础概念2.C语言接口回顾3.系统接口4.文件系统调用5.三个标准6.输出缓冲区 🌟🌟hello,各位读者大大们你们好呀🌟🌟 🚀🚀系列专栏:【Linux的…

股票K线基础知识2

光头光脚阳线 光头光脚阳线形态与特征描述 光头光脚阳线表示股票的最高价与收盘价相同,最低价与开盘价一样。光头光脚阳线上下不带影线,表明从一开盘买方就积极进攻,中间也可能出现买方与卖方的斗争,但买方发挥了最大力量。始终占…

18.JAVA之三大框架Spring、IOC和DI、拦截器、MVC项目、Mybatis持久层、动态SQL、SSM

一、Spring框架 1.1概述 其中最核心的是:IoC控制反转、DI依赖注入、Bean工厂、SpringAOP面向切面编程、事务控制。 Spring是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。 SpringMVC框架用来接受浏览器的请求和给浏览器做出响应 Mybatis…

C++:设计一个线程安全的队列

文章目录 1. 目的2. 实现?验证!makefileQueue 类的 public 成员单元测试 3. 实现 Queue 类的方案 1. 目的 串行的程序只用到单个 CPU 核心, 希望加速整个程序, 考虑使用多线程加速。典型情况下可以找到生产者、消费者&#xff0c…

基于ESP或ESP8266 单通道Lorawan网关硬件制作

软件代码设计资料下载链接》》 基于 Comresult PCB 的单通道网关 介绍 这是 ESP8266 LoRa 网关的最新版本。基于 ESP8266 mcu 的 LoRa 网关在过去几年里有了很大的发展。您想构建一个小型网关并保持尽可能多的 GPIO 引脚可用,Hallard 板是无与伦比的。另一种解决…

C++多态练习题

文章目录 1.虚函数的调用过程2.虚函数例题例题一例题二例题三例题四例题四 1.虚函数的调用过程 从汇编上面来看: []代表指针解引用操作 1.op指向test对象的首地址(存放vptr),并存放在eax里面; 2.将eax所指之物(虚表…

使用不同的梯度下降法优化算法

本篇将使用以下几个梯度下降算法进行对比: 不使用任何的优化算法(即整批数据集作为一次迭代更新梯度,也叫batch梯度下降,BGD) mini-batch梯度下降法(Mini-batchGD) 使用具有动量的梯度下降算法&…

无标签背景图(负样本)的拼图代码

训练目标检测模型有个很令人头疼的问题,就是有些特征与要训练的特征较为相似的背景区域也被误检出来(作为本应不该检测出来的负样本却被误检出为正样本的FP)。 根据这一问题的解决办法,除了可以对正样本特征较为模糊或者有歧义的样…

Intel SGX学习笔记(2):用数组向Enclave传递5个数实现自增操作

写在前面 1、实现一个简单的Intel SGX的应用:非安全区定义初始化一个数组,数组里面存储5个数,然后向安全区(enclave)传入,在安全区中进行加减乘除,然后返回。 2、Intel SGX开发初学整体思路&a…

代码随想录算法训练营day39 | 62.不同路径,63. 不同路径 II

代码随想录算法训练营day39 | 62.不同路径,63. 不同路径 II 62.不同路径解法一:动态规划解法二:深度搜索(明天补充)解法三:数论(明天补充) 63. 不同路径 II解法一:动态规…

RuoYi-Vue下载与运行

一、源码下载 若依官网:RuoYi 若依官方网站 鼠标放到"源码地址"上,点击"RuoYi-Vue 前端分离版"。 跳转至Gitee页面,点击"克隆/下载",复制HTTPS链接即可。 源码地址为:https://gitee.…

左值引用、右值引用,std::move() 的汇编解释

1:左值引用 引用其实还是指针,但回避了指针这个名字。由编译器完成从地址中取值。以vs2019反汇编: 如图,指针和引用的汇编代码完全一样。但引用在高级语言层面更友好,对人脑。比如可以少写一个 * 号和 -> 。 &…

F280049C实现Simulink调制,以及多个PWM实例之间的同步

文章目录 前言基本概念调制发波载波同步问题 前言 最近作实验碰到了载波不同步的问题,以前也有碰到过这个问题,现在终于解决了,做个记录。 为了以示区分,实例指ePWMx,x1,2,3,4,5,6,7,8;通道指ePWMxA/B&am…