首页 > 数据库 > 数据库开发技术 > 夏季的通透!MySQL 的可重复读怎么实现的?
MySQL的可重复读(Repeatable Read)是事务的隔离级别之一,它确保在一个事务中,多次读取同一数据的结果是一致的,即使有其他事务在并发修改数据。在可重复读隔离级别下,事务可以看到在事务开始前就已经存在的数据,并且在整个事务过程中,这些数据的可见性不会改变。
夏天了,都喜欢吃冰棍,就是那种通透的感觉,今天 V 哥的文章,也要让你感受一下,如何通透的理解这个问题:MySQL中可重复读的实现主要依赖于以下几个机制:
MVCC(多版本并发控制)是一种用于提高数据库系统并发性能的技术。它允许多个事务同时访问相同数据,而不会引起冲突,从而提高数据库的并发能力。以下是MVCC实现原理和机制的详细介绍:
1. 版本链(Version Chain)
在MVCC中,每行数据都可能有多个版本。这些版本通过一个版本链(也称为undo链)相互连接。每个版本包含了数据的快照,包括数据本身以及事务的元信息,如创建该版本的事务ID和时间戳。
2. Read View
当一个事务读取数据时,InnoDB会为该事务创建一个"Read View",它是一个数据的一致性快照。Read View包含了事务开始时所有已提交的数据版本,以及事务自己所做的修改。Read View确保了事务可以看到一致性的数据视图,即使其他事务在并发修改数据。
3. 一致性非锁定读取
事务读取数据时,不需要加锁,因为Read View会提供一个一致性的数据视图。这减少了锁的开销,提高了并发性能。
4. 写操作和Undo日志
当事务要修改数据时,InnoDB不会直接在当前数据上修改,而是通过Undo日志创建数据的一个新版本。这个新版本包含了修改前后的数据,以及事务的元信息。这样,其他事务仍然可以看到它们自己的Read View中的版本。
5. Gap Locks
为了维护数据的一致性,InnoDB在可重复读隔离级别下使用Gap Locks。Gap Locks锁定的是数据行之间的"间隙",而不是数据行本身。这可以防止其他事务在已锁定的间隙中插入新行,从而维护数据的一致性。
6. 版本链的清理
随着事务的提交或回滚,一些版本的数据不再被任何事务的Read View所需要。InnoDB会定期清理这些不再需要的版本,释放存储空间。这个清理过程称为"purge"。
7. 系统版本号(System Version Number, SVN)
每行数据都有一个系统版本号,用于标识该数据版本的创建时间。当事务尝试访问数据时,它会根据系统版本号和自己的Read View来确定应该读取哪个版本的数据。
MVCC的优缺点
优点:
缺点:
MVCC是现代数据库系统中实现高并发访问的关键技术之一,特别是在支持高并发读写操作的OLTP(在线事务处理)系统中。通过合理地使用MVCC,数据库可以提供更好的性能和一致性保证。
行级锁定是数据库管理系统中用于实现事务隔离级别的一种锁定机制,它允许系统锁定数据表中的单行或多行记录,以保证事务的原子性、一致性、隔离性和持久性。以下是行级锁定的实现原理和机制的详细介绍:
1. 锁定粒度
行级锁定的粒度是数据库锁定机制中最小的,它只锁定事务操作的特定行,而不是整个表或页面。这允许多个事务并发访问同一个表中的不同行,从而提高并发性能。
2. 锁的类型
行级锁定通常包括两种类型的锁:
3. 锁定机制
4. 锁的兼容性
不同类型的锁之间存在兼容性规则,以确保事务的正确执行。例如:
5. 死锁检测
数据库管理系统会定期检测死锁情况,即两个或多个事务相互等待对方持有的锁。如果检测到死锁,系统会选择回滚其中一个或多个事务以解决死锁。
6. 锁的释放
事务完成后,无论是提交还是回滚,都会释放它持有的所有锁。这允许其他等待的事务继续执行。
7. 索引和锁定
行级锁定通常依赖于索引。如果事务通过索引查找数据,数据库管理系统可以直接锁定相应的行。如果没有索引,数据库可能需要扫描整个表来找到匹配的行,这会降低性能。
8. 锁定协议
数据库管理系统实现行级锁定时,会遵循一定的锁定协议,如两阶段锁定协议,以确保事务的隔离性和系统的稳定性。
MVCC与行级锁定
在支持MVCC的数据库系统中,行级锁定通常与MVCC结合使用。MVCC通过维护数据的多个版本来处理并发访问,而行级锁定则确保事务在修改数据时不会与其他事务冲突。
行级锁定是一种有效的并发控制机制,它通过锁定数据行而不是整个数据表,提高了数据库的并发处理能力。然而,行级锁定也带来了额外的管理开销,并且在高并发场景下可能导致锁竞争和死锁,需要数据库管理系统进行精细的锁定管理。
间隙锁(Gap Lock)是数据库管理系统中用于处理并发控制的一种锁定机制,特别是在实现了多版本并发控制(MVCC)的数据库系统中,如MySQL的InnoDB存储引擎。间隙锁用于防止其他事务在已锁定的间隙中插入新行,从而维护数据的一致性和事务的隔离性。以下是间隙锁的实现原理和机制的详细介绍:
1. 间隙锁的定义
间隙锁锁定的是数据行之间的“间隙”,而不是具体的数据行本身。它用于保护一个范围内的记录,但不锁定记录本身。
2. 间隙锁的类型
间隙锁主要有两种类型:
3. 间隙锁的目的
间隙锁的主要目的是防止幻读(Phantom Reads)。幻读发生在一个事务在读取某个范围内的记录后,另一个事务插入了新的记录,导致第一个事务再次读取时结果不一致。
4. 间隙锁的实现
5. 间隙锁的兼容性
间隙锁与其他类型的锁(共享锁、排它锁)之间存在兼容性规则。例如:
6. 死锁检测
间隙锁的使用也需要考虑死锁检测机制。数据库管理系统会定期检测死锁情况,并采取措施解决,如回滚事务。
7. 间隙锁的释放
间隙锁通常在事务结束时释放,无论是提交还是回滚。这允许其他等待的事务继续执行。
8. 间隙锁的性能影响
虽然间隙锁可以防止幻读,提高数据的一致性,但它们也可能增加锁定的开销,降低并发性能。因此,数据库管理员需要根据具体的业务需求和系统负载来权衡间隙锁的使用。
9. MVCC与间隙锁
在支持MVCC的数据库系统中,间隙锁与MVCC一起工作,以提供更高级别的隔离性。MVCC通过保存数据的多个版本来处理并发读取,而间隙锁确保在这些版本的间隙中不会插入新的记录。
间隙锁是一种重要的锁定机制,特别是在需要防止幻读的场景中。然而,间隙锁的使用需要仔细考虑,以避免不必要的性能损失。数据库管理员应该根据具体的应用场景和事务特性来决定是否使用间隙锁。
通过这些机制的组合,MySQL的InnoDB存储引擎能够在可重复读隔离级别下提供稳定的数据视图,确保事务的一致性和隔离性。然而,这种隔离级别虽然提供了很好的数据一致性保证,但也可能引起性能问题,如锁的竞争和死锁。因此,在实际应用中需要根据业务需求和性能考虑来选择合适的隔离级别。
大实话:99%的CTO都是 Java 狂!
@好文推荐:
10个点介绍SpringBoot3工作流程与核心组件源码解析

找V哥

原文作者:Java架构栈;如有侵权,请联系管理员删除。