mysql隔离性结合case详细分析;一文掌握RR和RC的MVCC底层原理;四种隔离级别区别

MySQL的隔离是通过不同的隔离级别来实现的。
MVCC机制是实现RC和RR隔离级别的主要方法。
RU 和 Serialize 分别使用非阻塞和两阶段阻塞协议来实现。
下面详细介绍隔离的定义、MVCC的机制、MVCC的RR和RC的实现、四种隔离级别的区别以及案例分析。
1 .MySQL隔离和隔离级别。
隔离性定义:指事务A中特定数据变化的可见性或其他事务的连续性。
例如,事务 A 修改了数据,但在给定某个隔离级别的情况下,其他事务可能看不到这些更改。
四种隔离级别是: RU(ReadUncomfilled):存在“脏读”问题,即一个事务可以读取另一个未提交事务修改的数据。
RC(ReadCommited):解决了脏读问题,但存在不重复读的问题,即同一个数据在一个事务内多次读取,结果可能不同。
RR(RepeatableRead):解决了不可重复读的问题,但是存在幻读的问题,即一个事务内的多个请求可能会莫名产生额外的数据。
Serialization(可读串口):最高级别的隔离,解决了所有并发问题,但性能较差。
这是通过模拟顺序事务的执行来实现的。
2 、MVCC机制保证交易之间互不干扰。
目标:提高并发读性能并实现不同的隔离级别。
锁影响并发,不适合高并发读场景,因此引入了MVCC。
基本数据结构: 版本链:写入undo log,每个条目附加一个tri_id以指向先前修改的条目。
快照:本质就在minid和maxid。
minid记录当前已提交事务的事务ID,maxid记录当前最大事务ID。
read_view 快照针对每个选择并记录一组未提交的事务和最大ID。
Minid — 数组中最小的交易编号。
3 . RR和RC MVCC实现的详细解释。
RC 和 RR 隔离级别的区别: RC 隔离级别:每次执行 select 语句时都会创建一个读视图。
隔离级别 RR:第一次执行 select 语句时生成读视图。
MVCC中更新操作版本链:会复制版本链中的最新数据,然后将trx_id更改为删除操作的trx_id。
同时记录头信息中的标志(deleted_flag)会被写入true,表示当前记录已被删除。
当请求时,根据规则找到相应的记录。
如果delete_flag为true,则表示该记录已被删除,不会返回任何数据。
MVCC可读性规则:如果当前记录的事务的ID落在绿色部分(trx_id如果当前记录的交易ID落在红色部分(trx_id>max_id),则表示该版本是由未来启动的交易生成的,不可读。
如果当前记录的事务ID落在黄色部分(min_id<=trx_id<=max_id),则会出现两种情况: 如果当前记录的事务ID在未提交事务数组中,则该记录不可读。
如果当前记录的事务 ID 不在未提交事务数组中,则该记录可供读取。
4 .案例研究。
初始数据:name=lilei00,id=1 第一选择:创建快照读视图:[1 00,2 00]3 00,表示当前有1 00和2 00个未提交事务,当前最大事务为3 00。
版本链:lilei3 00(tri_id3 00true) -->lilei00(tri_id=1 )。
根据比较规则,3 00不在未提交数组中,因此可以读取,直接返回lilei3 00。
第二个选择:没有变化的快照,读取视图:[1 00,2 00]3 00。
版本链:lilei2 (tri_id2 00)-->lilei1 (tri_id2 00)-->lilei3 00(tri_id3 00true)-->lilei00(tri_id=1 )。
2 00是一个未提交的数组,所以在lilei3 00之前无法读取。
5 . RU和Serialize的实现方法。
执行CN: 不加锁,直接读取内存中的数据。
数据不一定存储在磁盘上,这可能会导致读取错误和不正确的读取问题。
串行化实现:最高级别的事务隔离,性能较低,模拟事务的串行执行而不是并行执行。
使用该层的应用程序必须准备好在序列化失败时重新启动事务。
遵循两阶段锁定(2 PL)协议:在事务中,所有锁定操作都在一个阶段中执行,并且不可能交替锁定和解锁。
所有并发运行的事务都遵循两阶段锁定协议,因此这些事务的任何并发调度都可以串行化。
6 、幻读和可重复读、快照读和当前读幻读和可重复读:不可重复读:在同一事务中两次读取现有数据不一致。
幻读:由于快照读没有被阻塞,当当前读和快照读混合时,会莫名其妙地出现额外的数字。
快照读和当前读: 快照读:通过MVCC(Void Log)实现,无需加锁,例如: select*from...where..... Current Read:读取最新版本,首先需要获取对应记录的锁,例如:选择*从...哪里...进行更新; select*from..where...lockinsharemodeupdate..;set..where.... 7 、解决RR隔离级别的幻读及适用场景。
解决幻读:使用下面的key(关键锁)来阻塞可以插入数据的地方。
适用场景:选择事务性结果一致性场景,例如同时执行多条查询语句,包括统计查询、报表查询等。
在这种场景下,多条查询的SQL必须保证整体读一致性。

MySQL 事务有原子性、隔离性、一致性和持久性四大特性,为什么偏偏给隔离性设置了级别?

讨论事务的四个主要属性:原子性、隔离性、一致性和持久性。
为什么要设置不同级别的隔离?事务的本质是保证数据操作的有效性,而隔离性是实现这一目标的关键。
当多个用户同时访问数据库时,隔离级别设置为不同级别,以平衡并发性和一致性。
让我们从定义事务开始。
事务是一个工作单元,由一系列数据库操作组成,这些操作要么全部成功,要么全部失败。
InnoDB存储引擎是MySQL默认使用的引擎,支持事务。
In MySQL, the default behavior of transactions is automatic submission, that is, each SQL statement constitutes a transaction and is submitted after automatic execution.然而,对于涉及多个SQL语句的业务流程,自动提交可能不是最好的选择。
因此,MySQL提供了通过BEGIN或STARTTRANSACTION手动启动事务的功能。
Another important concept in MySQL transaction management is the autocommit system variable, which specifies whether or not to commit automatically.默认情况下,autocommit是开启的,这意味着自动提交。
不过,这与手动操作事务并不冲突。
In a concurrent environment, uncontrolled transactional operations may lead to read consistency issues, such as dirty reads, non-reproducible reads, and ghost reads.这些问题是由于事务之间并发执行导致的数据不一致而产生的。
脏读是指一个事务读取的数据已经被另一个未提交的事务修改了;当一个事务两次读取相同的数据,并且数据内容不一致时,就会发生不可重复读;当一个事务两次读取结果集,但数据集不同时,就会发生幻读。
为了解决这些问题,SQL标准提出了隔离级别的概念。
MySQL 支持四种隔离级别,即 UNCOMMITTED、READCOMMITTED、REPEATABLEREAD 和 SERIALIZABLE。
隔离级别设置旨在通过控制事务的并发行为来减少或避免读一致性问题。
其中,序列隔离级别提供了最强的一致性保证,但牺牲了并发性能。
Conversely, the uncommitted read isolation level allows more concurrency, but has the lowest consistency requirements, which can easily cause read consistency problems.提供InnoDB存储引擎通过 REPEATABLEREAD 隔离级别下的 MVCC(多版本并发控制)机制实现更好的同步和一致性。
MVCC通过版本链记录数据的多个版本,保证给定时间点事务的一致性。
简而言之,隔离级别的设置就是为了在并发性和一致性之间找到一个平衡点。
不同的绝缘等级适用于不同的场景。
开发人员可以根据业务需求选择合适的隔离级别,以满足数据一致性和并发性能的要求。

示例MySQL事务隔离级别以及脏读、幻读、不可重复读

MySQL中的事务隔离级别包括四种类型:未提交读、已提交读、可重复读和序列化读。
下面详细介绍这些隔离级别:脏读、幻读、不可重复读。
执行并发事务时出现的问题 脏读:一个事务读取了已经被另一个尚未提交的事务修改过的数据。
例如,A时段开始交易后,小王的账户余额增加了5 0,但没有提交。
会话B读取到小王的账户余额为1 5 0,如果会话A随后回滚,那么会话B读取到的1 5 0就是脏数据。
不可重复读取:这意味着在同一事务中多次读取同一数据集,但结果不同。
例如,会话A在开始一笔交易后第一次读取小王的账户余额,变为1 00。
会话B将小王的账户余额增加5 0,提交给另一笔交易。
会话A再次读取小王的账户余额,将其修改为1 5 0,这就导致了不可重复读。
幻读:当一个事务读取特定范围内的记录时,另一个事务会在该范围内插入一条新记录。
当先前的事务重新读取该范围内的记录时,它会读取先前未读取的数据。
例如,会话A开始交易后,第一个查询余额为1 00的账户的只有小王。
会话B将余额为1 00的小张账户插入并提交到另一笔交易中。
当会话A重新查询余额为1 00的账户时,会读取小王、小张两个账户,导致幻读。
SQL 标准指定了四种隔离级别: 未提交读:在事务提交之前,更改对其他事务可见。
脏读、不可重复读和虚拟读都可能发生在这个级别。
读提交:事务提交后,更改对其他事务可见。
在此级别,可能会发生不可重复读和幻读,但不会发生脏读。
可重复读取:事务执行期间显示的数据始终与事务开始时显示的数据匹配。
在此级别,可以发生虚拟读,但不会发生脏读和不可重复读。
序列化:对于同一行记录,“写”加“写锁”,“读”加“读锁”。
当发生读写锁冲突时,后面访问的事务必须等待前一个事务完成才能继续执行。
此级别不会发生脏读、不可重复读和幻读。
MySQL支持四种隔离级别:MySQLInnoDB存储引擎支持上述四种隔离级别。
与 SQL 标准不同,InnoDB 在可重复读隔离级别使用 Next-KeyLock 锁定算法来防止创建幻读。
也就是说,在这个级别上,可以充分保证事务的隔离性要求。