美文网首页
事务隔离级别

事务隔离级别

作者: LENN123 | 来源:发表于2020-04-07 15:47 被阅读0次
引言

事务是一组要么全部执行,要么全部不执行的语句(满足原子性)。事务在定义上必须要满足ACID四大要素,即Atomicity原子性Consistency一致性Isolation隔离性Durability持久性MysqlInoodb存储引擎是支持事务的,其满足ACID四大特性。其中,除了隔离性以外的三大特性均由redo logundo log来保证,而隔离性由锁来提供。锁机制可以保证最高程度上的隔离性, 例如串行的依次执行多个事务,从而保证在并发修改下的正确性。但事实上这样的开销太大了。为了在正确性和效率之间折衷,SQL标准,定义了四种隔离级别供使用者选择。

隔离级别 脏读 不可重复读 幻读
READ UNCOMMITED 可能发生 可能发生 可能发生
READ COMMITED 不可能发生 可能发生 可能发生
REPEATABLE READ 不可能发生 不可能发生 可能发生
SERIALIZABLE 不可能发生 不可能发生 不可能发生

四种隔离级别从上到下依次提高,隔离级别越低,事务所持有的锁越少,或时间越短。此外,以上的四个隔离级别只是SQL定义的标准,提供参考。具体的存储引擎在实现时往往有自己的一套标准,比如Inoodb默认情况下是REPEATABLE READ的,但实际上得益于间隙锁,在这个级别下Inoodb也杜绝了幻读现象的发生。下面通过举例的方式来解释什么是脏读、不可重读、幻读。在此之前先建一张示例表,其中id是INT类型的主键。

 CREATE TABLE tb1(
     id INT,
     name VARCHAR(100),
     PRIMARY KEY(id)
 )Engine=InnoDB CHARSET=utf8;

在这张表里插入一行演示数据

INSERT INTO tb1 VALUES(1, 'Tom');
+----+------+
| id | name |
+----+------+
|  1 | Tom  |
+----+------+
脏读

只有READ UNCOMMITED隔离级别下会发生,如图READ UNCOMMITED这个名字一样,脏读就是读到了(其他事务)修改但未提交(uncommited)的脏数据。例如两者同时进行的事务A和事务B,事务B对某个记录执行的修改操作,再没有提交之前就可以被事务A察觉到,那么此时就发生了脏读现象,其时序图如下。

发生脏读

在实验之前我们首先要在每个事物开始之前修改当前会话的隔离级别为READ UNCOMMITED

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT @@tx_isolation
+------------------+
| @@tx_isolation   |
+------------------+
| READ-UNCOMMITTED |
+------------------+

然后依照上面的执行流程执行SQL语句,可以发现在事务A第一次SELECT的时候,此时主键id=1数据还未被更改,依然为Tom

SELECT * FROM tb1 WHERE id=1;
+----+------+
| id | name |
+----+------+
|  1 | Tom  |
+----+------+

当第二次执行SELECT查询时,此时数据却变为Ben且事务B执行更新操作后还未提交。

SELECT * FROM tb1  WHERE id = 1;
+----+------+
| id | name |
+----+------+
|  1 | Ben  |
+----+------+

此时发生了脏读现象。

不可重复读

不可重复读,是指在一个事务中,先后两次对同一条记录的读取结果出现不一致的情况,也就是说该记录被其他事务修改过了,注意这里要和脏读区分开,在脏读里,事务B即使未提交(uncommited),也可以影响到事务A的查询结果,而在不可重复读条件下,未提交的事务B是不会影响到事务A的查询结果的(未发生脏读),只有当是事务B提交后,才会影响到事务A的查询结果,下图给出发生不可重复读现象的执行时序图,图中黄色部分重点强调了commit的时间点,用以与脏读现象区分。

不可重复读

依照这个时序图来依次执行sql语句,首先,让我们把隔离级别改成READ COMMITED,这个级别下脏读不会发生,但会出现不可重复读现象。

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+

先看下目前tb1表中的记录

SELECT * FROM tb1;
+----+------+
| id | name |
+----+------+
|  1 | Tom  |
+----+------+

事务A开始事务,执行第一次查询语句,然后等待

# 事务A
BEGIN;
SELECT * FROM tb1 WHERE id = 1;
+----+------+
| id | name |
+----+------+
|  1 | Tom  |
+----+------+

事务B开始事务,更新id=1的记录name字段为ben,然后提交

# 事务B
BEGIN;
UPDATE tb1 SET name = 'Ben' WHERE id = 1;
COMMIT;

再回到事务A,再执行第二次查询,发现记录已经被已提交的事务B修改了,发生了不可重复读现象。

# 事务A
 SELECT * FROM tb1 WHERE id = 1;
+----+------+
| id | name |
+----+------+
|  1 | Ben  |
+----+------+
幻读

幻读是说,在一个事务中,先后两次范围查询,由于另一个事务的插入操作,导致第二次查询结果的记录数比第一次多,凭空多出了一些记录的现象。其执行时序图如下。


幻读

注意接下来的实验中,不能将隔离级别设置为REPEATABLE READ,因为之前说过,在Innodb中使用了间隙锁,在这个REPEATABLE READ级别也不会发生幻读,所以这里还是用READ-COMMITTED隔离级别做演示。

首先开始事务A,进行第一次查询所有主键值id>=1的记录,然后等待。

# 事务A
BEGIN;
SELECT * FROM tb1 WHERE id >= 1;
+----+------+
| id | name |
+----+------+
|  1 | Tom  |
+----+------+

开始执行事务B,插入id=2 name='Ben'的记录,并提交

BEGIN;
INSERT INTO tb1 VALUES(2, 'Ben');
COMMIT;

回到事务A,再次查询,发现多出了上次查询中不存在的记录(2, 'Ben'),发生了幻读现象

SELECT * FROM tb1 WHERE id >= 1;
+----+------+
| id | name |
+----+------+
|  1 | Tom  |
|  2 | BEN  |
+----+------+

相关文章

  • Spring 中的事务隔离级别

    什么是事务隔离级别? 事务隔离级别是对事务 4 大特性中隔离性的具体体现,使用事务隔离级别可以控制并发事务在同时执...

  • MySQL_tx_isolation

    事务隔离级别 一、数据库事务隔离级别数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、...

  • MySQL事务隔离级别和实现原理,看这一篇就够了!!!

    经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗,事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么...

  • 面试题

    基础知识 1、事务隔离级别 补充: 1、事务隔离级别为读提交时,写数据只会锁住相应的行 2、事务隔离级别为可重复读...

  • 数据库事务相关

    事务隔离级别(tx_isolation)mysql 有四级事务隔离级别 每个级别都有字符或数字编号 级别symbo...

  • 关于Spring的事务Transactional,锁同步,并发线

    Spring事务传播机制和数据库隔离级别 在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同 。...

  • Mysql事务

    事务隔离级别 事务隔离级别有四种:read-uncomitted,read-commited,repeatable...

  • mysql事务-2020-11-21

    use test查询事务隔离级别:select @@tx_isolation; 设置事务隔离级别://全局的set...

  • MYSQL事务

    常用语句 MYSQL事务,锁表 事务控制语句 事务的隔离级别 隔离级别描述产生风险READUNCOMMITTED ...

  • 事务

    事务隔离级别 隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了...

网友评论

      本文标题:事务隔离级别

      本文链接:https://www.haomeiwen.com/subject/omciphtx.html