mysql 行锁为什么不能阻止幻读?

本文深入探讨了数据库中的幻读现象,特别是在MySQL的REPEATABLEREAD隔离级别下,如何通过加锁解决不可重复读问题,但仍然无法避免新插入记录导致的幻读。理解幻读对数据库一致性的影响及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先要知道什么是幻读。
幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次没有看到的行。
比如下图的3个session 中
T1,T3,T5 查询的结果都不一样。
T3 属于不可重复读。
T5 就是幻读 因为T4刚插入了 一条数据在这里插入图片描述

我们把数据库调成REPEATABLE READ重复读在执行一次会出现如下
REPEATABLE READ

由于 session A 把所有的行都加了写锁,所以 sessionB 在执行第一个update 语句的时候就锁住了,需要T6时刻提交后sessionB才能执行.所以T3 属于不可重复读 的问题解决了。

但是T5的幻读还存在,因为在T3时刻我们给所有的行都加了锁,但是新插入的行不存在,所以没发加锁。
也就是说,即使把所有记录都加上锁,也无法阻止新插入的记录。

这就是为什么mysql行锁解决方案无法阻止幻读。

<think>好的,我现在需要回答用户关于MySQL作用对象的问题。根据用户提供的参考资料,我需要仔细梳理这些信息,确保回答准确。 首先,用户引用了四篇资料,其中引用[1]提到定的是具体的数据。引用[2]指出加对象是索引,基本单位是next-key lock,并且对于唯一索引和非唯一索引有不同的范围。引用[3]和[4]提供了具体的加方式和类型,比如共享和排他,以及如何查看的信息。 接下来,我需要整理这些信息。的作用对象确实是索引,而不是物理上的数据。这是因为InnoDB使用索引来实现。如果没有索引,会退化为表,这会影响并发性能。例如,当使用主键索引(唯一索引)时,定的范围更精确,可能只是记录,而非唯一索引可能需要间隙或next-key lock来避免。 另外,需要注意的类型和模式,比如记录、间隙、next-key lock的区别,以及意向的作用。引用[4]中的ENGINE_TRANSACTION_ID和LOCK_DATA等字段可以帮助理解的具体信息,比如定的主键值。 可能用户还会混淆和表的区别,需要明确说明的粒度更细,只有在有合适索引的情况下才能生效。此外,不同事务隔离级别对的影响,比如可重复(RR)和已提交(RC)下为不同,但用户的问题主要聚焦在定对象,所以这部分可能不需要深入展开。 最后,确保回答结构清晰,分点说明,并引用相关文献支持每个观点。同时,生成的相关问题要围绕的机制、不同索引的影响以及优化等方面,帮助用户进一步了解。</think>### MySQL的作用对象解析 MySQL(Row-level Lock)的定对象是**索引项**,而非物理数据。这一机制与存储引擎的实现密切相关,尤其是InnoDB引擎通过索引实现。以下是具体分析: --- #### 1. **基于索引** - **核心机制**:InnoDB的通过索引实现。如果查询条件未使用索引,会退化为**表级**,导致并发性能下降[^2][^4]。 - **示例**: - 对主键(唯一索引)的条件查询(如`WHERE id=1`),会直接在索引项上加。 - 非唯一索引的查询可能需要加**间隙**(Gap Lock)或**next-key lock**,以防止其他事务插入导致。 --- #### 2. **的粒度与索引类型** - **唯一索引**:定**具体索引项**或**记录**(Record Lock),范围更精确。例如: ```sql SELECT * FROM user WHERE uid=1 FOR UPDATE; -- 对uid=1的主键索引加排他 ``` - **非唯一索引**:可能扩展为**间隙**或**next-key lock**,定一个索引范围。例如: ```sql -- 假设age是非唯一索引,且存在age=20的记录 SELECT * FROM user WHERE age=20 FOR UPDATE; -- 可能定age=20的索引项及相邻间隙,阻止其他事务插入age=20的数据 ``` --- #### 3. **的查看与验证** 通过`INNODB_LOCKS`或`performance_schema.data_locks`表可查看的详细信息[^4]: - `LOCK_TYPE`:`RECORD`表示。 - `INDEX_NAME`:显示定的索引名称(如`PRIMARY`)。 - `LOCK_DATA`:记录定的具体索引值(如主键值`7742`)。 --- #### 4. **特殊场景与注意事项** - **无索引查询**:若条件字段无索引,退化为**表级**,此时并发写操作会被阻塞[^1]。 - **意向(Intention Locks)**:表级,用于快速判断表中是否存在(如`IX`意向排他)[^3]。 --- ### 总结 MySQL定对象是**索引项**,其具体为取决于索引类型(唯一/非唯一)和查询条件。合理设计索引是优化并发性能的关键[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值