怎样利用MySQL的Lock In Share Mode避免脏读

雨墨大大_9115

雨墨大大_9115

2026-10-15

562人浏览

原创

lock in share mode 不能防止脏读,它只防止其他事务修改已读数据;防脏读靠的是事务隔离级别(如read committed)和mvcc机制,而非共享锁本身。

怎样利用mysql的lock in share mode避免脏读

Lock IN SHARE MODE 不能防止脏读,它只防写冲突

直接说结论:LOCK IN SHARE MODE 不是用来防脏读的。它加的是共享锁(S 锁),允许其他事务并发读,但会阻塞其他事务对同一行执行 UPDATE、DELETE 或 SELECT FOR UPDATE —— 也就是说,它防的是「别人改我刚读过的数据」,而不是「我读到别人还没提交的数据」。

脏读的本质是读到了未提交的变更。而 LOCK IN SHARE MODE 并不改变事务的隔离级别,也不强制让当前事务「只看已提交版本」。如果当前会话隔离级别仍是 READ UNCOMMITTED,那即使加了 LOCK IN SHARE MODE,照样可能读到脏数据。

真正起作用的是隔离级别本身。InnoDB 的 READ COMMITTED 和 REPEATABLE READ 都靠 MVCC 实现一致性读,天然屏蔽未提交数据 —— 这才是防脏读的主力。

什么时候该用 LOCK IN SHARE MODE

它的典型用途是:需要确保自己读到的数据,在后续操作中不会被别人覆盖,且你**不打算自己修改它**,只是要基于它做判断或关联查询。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • 比如库存校验后,仅记录日志或生成报表,不扣减;
  • 读取用户配置后,用于下游服务路由,不更新配置本身;
  • 多个服务并行读取同一个状态码表,但要避免在读期间被 DDL 修改(注意:DDL 受 MDL 锁控制,不是这个锁管的)。

这时 LOCK IN SHARE MODE 能防止其他事务在你读完后立刻 UPDATE 同一行,造成你依据过期快照做决策。但它不保证你读到的就是最新已提交值 —— 因为 MVCC 快照已在事务首次 SELECT 时确定。

为什么容易误以为它能防脏读

常见混淆点有三个:

  • 把「加锁等待」当成「自动读已提交版本」:如果另一事务正持有 X 锁未提交,SELECT ... LOCK IN SHARE MODE 会阻塞,直到对方提交或回滚;一旦释放锁,你读到的是对方提交后的值 —— 但这只是巧合,不是机制保障;
  • 混用了 SELECT ... LOCK IN SHARE MODE 和 SELECT ... FOR UPDATE:后者加 X 锁,阻塞所有并发读写,常用于「读-改」闭环,看起来更“安全”,但防脏读的功劳仍属于隔离级别;
  • 测试环境默认隔离级别是 REPEATABLE READ,本身就防脏读,误把隔离级别功劳记在锁上。

正确组合:隔离级别 + 显式锁才可靠

若业务真需要强一致性读(比如金融类核对),推荐组合:

  • 会话级设为 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED(避免长事务拖慢 MVCC 清理);
  • 关键读操作用 SELECT ... FOR UPDATE,哪怕后续不改,也确保读到的是最新已提交版本,并阻止别人并发改;
  • 避免在 REPEATABLE READ 下依赖 LOCK IN SHARE MODE 做实时性判断——它的快照可能早已滞后。

最易被忽略的一点:LOCK IN SHARE MODE 对 INSERT 不起作用,也不阻止幻读;想锁住范围(比如防止新插入满足条件的行),得靠 SELECT ... FOR UPDATE 配合索引使用 Next-Key Lock。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4243

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

891

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1109

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6161

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3003

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6120

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8261

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1130

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

992

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 187人学习