我的编程空间,编程开发者的网络收藏夹
学习永远不晚

for update 详解及实战

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

for update 详解及实战

一、for update 是什么?

“SELECT … FOR UPDATE” 是一种在 SQL 中常用的锁定查询语句。它可以在查询数据时同时对查询结果中的记录加上排他锁 ,防止其他事务修改或删除这些记录。使用方法为在 SELECT 语句中加上 FOR UPDATE 子句。
例如:
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
这会查询 accounts 表中 id 为 1 的记录,并对这些记录加上排他锁。

二、我们通常什么情况下会用到它?

1 .在我们的实际业务场景中,有些情况并发量不太高,为了保证数据的正确性,使用悲观锁也可以

1.分布式下并发扣减库存的操作(原来我们系统运用乐观锁限制 但是后来发现多扣减的问题 后来改用了 for updte 行锁的方式) 这个我会用一个案例来讲解说明2.用户扣减积分,系统自动赠送积分的并发情况,有必要加悲观锁限制一下,防止出现积分加错的情况发生.

三、select……for update会锁表还是锁行?

我将从三方面演示这个问题(以下内容都为本人亲测 mysql 5.7 数据库引擎为 innodb 隔离级别为数据库默认隔离级别 (可重复读) )
首先需要关闭数据库事务的自动提交变更为手动提交事务 set autocommit=0
sql执行脚本:
在这里插入图片描述

上面需要sql执行脚本的可以联系我 这里我就直接粘贴图片了
在这里插入图片描述

以下三种情况都需要打开两个测试窗口

1.有主键的情况下

窗口1:执行如下命令:

start transaction ;select service_name from chenwx_code where id=1 for update;

将id为1的行数据锁住 等待执行commit 语句
在这里插入图片描述
窗口2:执行如下命令:

update chenwx_code set is_deleted = is_deleted - 1 where id = '2';update chenwx_code set is_deleted = is_deleted - 1 where id = '1';

上面的命令
id 为 2可以正常执行成功
id为1 的数据会阻塞等待。

测试id 为 2修改操作正常执行成功
在这里插入图片描述
窗口2 因为开启了事务手动提交所以需要正常手动commit 数据才能执行修改数据操作

执行更新id为1的数据显示锁等待超时 超过一定时间会显示锁等待超时错误
在这里插入图片描述

1 .以上说明有主键的情况下执行for update语句利用主键开启事务查询会锁住当前行数据 ,不会锁住其他行数据

现在执行窗口2行锁事务执行没有超时的情况下正常扣减的情况
在这里插入图片描述

上面 主键1和主键2的is_deleted值都为 5
执行窗口1:
执行 1 .start transation 2.和for update 查询语句 可以看到返回主键id为1的 is_deleted 的值为5

在这里插入图片描述
执行窗口2:
执行 1 .start transation 2.和 for update id 为1的修改语句 可以看到数据显示正在执行一直等待中…

在这里插入图片描述
接着在执行窗口1 提交事务 commit 显示提交成功
在这里插入图片描述
窗口2显示返回更新成功 说明窗口2的事务一直在阻塞等待窗口1的事务提交
在这里插入图片描述
最终数据返回执行结果为 主键id为1的 is_deleted值减1成功返回4
在这里插入图片描述

2.有普通索引或者唯一索引的情况下

亲测普通索引和唯一索引都可以的 执行情况和主键id是一致的下面是示例
现在拿普通索引来看一下执行情况
窗口1:执行start transaction 和 根据索引查找for update语句 执行结果返回is_deleted为4的执行结果

窗口2:执行start transaction 和 根据索引字段为service_name= base2的值更新字段is_deleted的值减1正常执行并且返回成功
在这里插入图片描述
接着在修改索引字段为service_name= base1的值更新字段is_deleted的值减1则显示这行数据处于阻塞状态
在这里插入图片描述
此时执行窗口1执行commit操作 提交返回成功
在这里插入图片描述
然后快速的打开窗口2显示修改成功
在这里插入图片描述
窗口2提交commit操作则显示成功
在这里插入图片描述
此时查看表里面service_name=base1的数据中的is_deleted字段变为3 说明修改大成功
在这里插入图片描述

3.没有索引的情况下

窗口1:执行start transaction 和 根据没有索引的字段执行 for update查询语句 执行结果返回service_name=base1的这行所有数据
在这里插入图片描述
窗口2:执行start transaction和修改service_name=base2的这行数据则显示base2的数据处于阻塞状态
因为修改的数据不是同一行数据也就是说不是锁住的行数据 所以说是表锁住了而不是行锁

在这里插入图片描述
接在窗口1执行commit操作提价数据
在这里插入图片描述
紧接着打开窗口2 此时窗口2修改的这一行数据已经显示执行成功了所以说是表锁住了
在这里插入图片描述

四、项目中的真实应用

1.首先开启spring事务

2.执行修改操作(业务逻辑) (根据主键或者有索引的字段进行for update查询 此操作为行锁)

3.最后返回执行结果给前端做展示

代码情况如下所示

//开启事务   spring默认的隔离级别 @Transactional(rollbackFor = Exception.class)//根据业务执行逻辑如下//1 先使用行锁 锁住当前行数据GoodsSku goodsSku = goodsSkuService.getBaseMapper().selectList(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getId, proOrderGenerateSpuVo.getSkuId()).select(GoodsSku::getStock, GoodsSku::getId, GoodsSku::getVersion).last(" for update")//2 在执行修改库存操作boolean result = goodsSkuService.updateById(goodsSku);//3 提交返回数据return vo

五、想要使用for update一定要开启事务否则不生效

总结

希望大家多多支持我是维新的博客 有什么问题可以咨询我

来源地址:https://blog.csdn.net/qq_39220971/article/details/130245812

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

for update 详解及实战

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

for update 详解及实战

文章目录 一、for update 是什么?二、我们通常什么情况下会用到它?1 .在我们的实际业务场景中,有些情况并发量不太高,为了保证数据的正确性,使用悲观锁也可以 三、select……for update会锁表还是锁行?1.
2023-08-20

MySQL for update锁表还是锁行校验(过程详解)

MySQLFORUPDATE子句可获取记录的排他锁,防止其他事务在读取记录时修改或删除。MySQL提供表锁(锁定整个表)和行锁(仅锁定查询涉及的行)。表锁提供最高并发控制,但性能下降。行锁允许其他事务访问未锁定的行,并发性更好。选择锁模式取决于应用程序需求,如高并发或防止幻象读。示例:锁表:SELECT*FROMtable_nameFORUPDAT锁行:SELECT*FROMtable_nameFORUPDATEROW_LOCK=1最佳实践:谨慎使用FORUPDATE,尽可能使用行锁,优化查询,并在事务中
MySQL for update锁表还是锁行校验(过程详解)
2024-04-02

HTTP中ETag语法及使用实战详解

这篇文章主要为大家介绍了HTTP中ETag语法及使用实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-07

React18之update流程从零实现详解

这篇文章主要为大家介绍了React18之update流程从零实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-10

ElasticSearch动态映射实战详解

这篇文章主要为大家介绍了ElasticSearch动态映射实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-31

PHP 设计模式实战详解

设计模式为软件设计提供经过验证的解决方案,解决常见编程问题。本文深入探讨 php 中的常用设计模式,并通过实战案例进行阐述,涵盖单例模式、工厂方法模式和观察者模式。PHP 设计模式实战详解设计模式为软件设计提供了一套经过验证的解决方案,以
PHP 设计模式实战详解
2024-05-07

编程热搜

目录