【mysql】事务的隔离级别有哪些?各个级别造成的问题是什么?Innodb分别是如何解决他们的?

上篇文章总结了有关事务的原子性,持久性和一致性【mysql】Innodb存储引擎是如何保证事务的ACID四个原则的,接下来是事务的隔离性。

事务隔离级别

  1. READ UNCOMMITTED : RU 称为浏览访问,可以读取事务未提交的数据。
  2. READ COMMITTED : RC 称为游标稳定,只能读取已经提交事务的数据。
  3. REPEATABLE READ: RR 可重复读。事务在执行过程中看到的值和事务开始时的值是一样的。
  4. SERIALIZABLE : SR 序列化。所有事务按照次序依次执行。当一个事务开始未提交时,其他事务均不能执行。

各个事务级别所造成的问题以及原因

  1. RU:

    问题:读取脏数据,不可重复读,幻像
    原因:在RU隔离级别下,读未提交的数据,所以,当事务还没有提交时,数据并不是最终的数据,另一个事务就有可能读取到脏数据。

  2. RC:

    问题:不可重复读,幻读
    原因:
    不可重复读:在对数据进行修改时,会产生undo log,在undo log中,数据会有多个版本的快照数据这种技术成为行多版本技术(请阅读下面 undo log 存储版本链)。在RC级别下,innodb存储引擎每次读取的历史版本是最新的版本数据,因此,当有新的事务提交产生新的版本数据时,RC级别读取到的数据会发生不一致这种现象称为不可重复读(每次select会产生一个新的readView导致)。
    幻读:在事务执行select操作加锁时,仍然可以进行insert操作对数据进行更改,再次执行select操作得到的结果集不一致的问题。这是因为在RC级别下不支持间隙锁,当select时加锁只能对记录本身的索引值加锁,不能对范围进行加锁,以致于可以继续插入范围内的数据造成幻读(下面解决方案中会举例说明)。

  3. RR

    问题:在RR级别下,innodb存储引擎解决了RC下的问题。可以达到隔离性的要求。

  4. SR
    此级别下由于是一个事务执行完成,另一个事务才能开始执行,事务级别最高,因此可以达到隔离性。

undo log 存储的版本链

版本链类其实是采用了乐观锁的机制。
在InnoDB引擎表中,它的聚簇索引记录中有两个必要的隐藏列:

  • trx_id
    这个id用来存储的每次对某条聚簇索引记录进行修改的时候的事务id。
  • roll_pointer
    每次对哪条聚簇索引记录有修改的时候,都会把老版本写入undo日志中。这个roll_pointer就是存了一个指针,它指向这条聚簇索引记录的上一个版本的位置,通过它来获得上一个版本的记录信息。(注意插入操作的undo日志没有这个属性,因为它没有老版本)

对于不同的操作,存储的数据如下:
SELECT
  innodb会根据以下两个条件检查每行记录:
    a.innodb只查找版本号早于当前事务版本的数据行,<=当前事务版本号,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的

b.行的删除版本要么未定义,要么大于当前的事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。

INSERT
  INNODB为新插入的每一行保存当前系统版本号作为行版本号
DELETE
  innodb为删除的每一行保存当前系统版本号作为行删除标识
UPDATE
  innodb为插入一行新纪录,保存当前系统版本号为行版本号,同时保存当前系统版本号到原来的行作为行删除标识

  1. RR :在innodb存储引擎中,已基本解决以上的问题,可以达到和SR相同效果的事务隔离级别
  2. SR:有事务按照次序依次执行。当一个事务开始未提交时,其他事务均不能执行。不会出现以上问题。

问题描述
1、脏读:读到未提交事务数据时,称为脏读。即读到脏数据,并不是事务最终的数据。
2、不可重复读:是幻像问题中的一种。在事务进行中,重复读取统一条记录,显示的数据不同,称为不可重复读。
3、幻读:是幻像问题的一种。在事务进行中,重复读取记录,得到的记录数与之前不一致。如:在同一个事务中第一次读取有5条记录,第二次读取为6条记录,出现了幻读现象。

不可重复读和幻读都是幻像问题的一种表现形式。

解决方案

1、脏读:将数据库隔离级别修改为READ COMMITTED。只能读取提交事务的数据即可。在mysql数据库中读取的是事务版本号比自己小的数据。

2、不可重复读:在RC 级别由于上面所说的读取的历史数据版本总是为最新的版本,这个跟ReadView相关,每次select会生成一个新的ReadView,所以造成多次查询结果数据不一致。

解决方案:将隔离级别修改为REPEATABLE REA

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值