简述MySql四种事务隔离级别

隔离级别:

隔离性其实比想象的要复杂。 在SQL标准中定义了四种隔离级别, 每一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

下面简单地介绍一下四种隔离级别。

1.READ UNCOMMITTED(未提交读)

在 READ UNCOMMITTED级别, 事务中的修改, 即使没有提交, 对其他事务也都是可见的。 事务可以读取未提交的数据, 这也被称为脏读 (Dirty Read). 这个级别会导致很多问题,从性能上来说, READ UNCOMMITTED 不会比其他的级别好太多, 但却缺乏其他级别的很多好处, 除非真的有非常必要的理由, 在实际应用中一般很少使用。

(1)所有事务都可以看到其他未提交事务的执行结果

(2)本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少

(3)该级别引发的问题是——脏读(Dirty Read):读取到了未提交的数据

#首先,修改隔离级别
set tx_isolation='READ-UNCOMMITTED';
select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+#事务A:启动一个事务
start transaction;
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+#事务B:也启动一个事务(那么两个事务交叉了)
在事务B中执行更新语句,且不提交
start transaction;
update tx set num=10 where id=1;
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+------+------+#事务A:那么这时候事务A能看到这个更新了的数据吗?
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 10 | --->可以看到!说明我们读到了事务B还没有提交的数据
| 2 | 2 |
| 3 | 3 |
+------+------+#事务B:事务B回滚,仍然未提交
rollback;
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+#事务A:在事务A里面看到的也是B没有提交的数据
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 1 |  --->脏读意味着我在这个事务中(A中),事务B虽然没有提交,但它任何一条数据变化,我都可以看到!
| 2 | 2 |
| 3 | 3 |
+------+------+

2.READ COMMITTED(提交读)

大多数数据库系统的默认隔离级别都是READ COMMITTED,MySQL不是.READ COMMITTED满足前面提到的隔离性的简单定义:一个事务开始时,只能“看见”已经提交的事务所做的修改。 换句话说, 一个事务从开始直到提交之前, 所做的任何修改对其他事务都是不可见的。 这个级别有时候也叫做不可重复读 (nonrepeatableread),因为两次执行同样的查询,可能会得到不一样的结果。

(1)这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)

(2)它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变

(3)这种隔离级别出现的问题是——不可重复读(Nonrepeatable Read):不可重复读意味着我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果。

导致这种情况的原因可能有:

(1)有一个交叉的事务有新的commit,导致了数据的改变;

(2)一个数据库被多个实例操作时,同一事务的其他实例在该实例处理其间可能会有新的commit

#首先修改隔离级别
set tx_isolation='read-committed';
select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+#事务A:启动一个事务
start transaction;
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+#事务B:也启动一个事务(那么两个事务交叉了)
在这事务中更新数据,且未提交
start transaction;
update tx set num=10 where id=1;
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+------+------+#事务A:这个时候我们在事务A中能看到数据的变化吗?
select * from tx; --------------->
+------+------+    |
| id | num |    |
+------+------+    |
| 1 | 1 |--->并不能看到! |
| 2 | 2 |    |
| 3 | 3 |    |
+------+------+    |——>相同的select语句,结果却不一样
|
#事务B:如果提交了事务B呢?   |
commit;      |
|
#事务A:       |
select * from tx; --------------->
+------+------+
| id | num |
+------+------+
| 1 | 10 |--->因为事务B已经提交了,所以在A中我们看到了数据变化
| 2 | 2 |
| 3 | 3 |
+------+------+

3.REPEATABLE READ (可重复读)

REPEATABLE READ解决了脏读的问题。 该级别保证了在同一个事务中多次读取同样记录的结果是一致的。 但是理论上, 可重复读隔离级别还是无法解决另外一个幻读(Phantom Read)的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插人了新的记录, 当之前的事务再次读取该范围的记录时, 会产生幻行 (Phantom Row).InnoDB和XtraDB存储引擎通过多版本并发控制 (MVCC, Multiversion Concurrency Control) 解决了幻读的问题。

(1)这是MySQL的默认事务隔离级别

(2)它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行

(3)此级别可能出现的问题——幻读(Phantom Read):当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的幻影行

(4)InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题

#首先,更改隔离级别
set tx_isolation='repeatable-read';
select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+#事务A:启动一个事务
start transaction;
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+------+#事务B:开启一个新事务(那么这两个事务交叉了)
在事务B中更新数据,并提交
start transaction;
update tx set num=10 where id=1;
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+------+------+
commit;#事务A:这时候即使事务B已经提交了,但A能不能看到数据变化?
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 1 | --->还是看不到的!(这个级别2不一样,也说明级别3解决了不可重复读问题)
| 2 | 2 |
| 3 | 3 |
+------+------+#事务A:只有当事务A也提交了,它才能够看到数据变化
commit;
select * from tx;
+------+------+
| id | num |
+------+------+
| 1 | 10 |
| 2 | 2 |
| 3 | 3 |
+------+------+

4.SERIALIZABLE(可串行化)

SERIALIZABLE是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读的问题.简单来说,SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。 实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下, 才考虑采用该级别。

(1)这是最高的隔离级别

(2)它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。

(3)在这个级别,可能导致大量的超时现象和锁竞争

#首先修改隔离界别
set tx_isolation='serializable';
select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+#事务A:开启一个新事务
start transaction;#事务B:在A没有commit之前,这个交叉事务是不能更改数据的
start transaction;
insert tx values('4','4');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
update tx set num=10 where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

以上就是简述MySql四种隔离级别的详细内容,更多关于MySQL 隔离级别的资料请关注我们其它相关文章!

(0)

相关推荐

  • MySQL中Innodb的事务隔离级别和锁的关系的讲解教程

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过分析MySQL中InnoDB引擎的加锁机制,来抛砖引玉,让读者更好的理解,在事务处理中数据库到底做了什么. 一次封锁or两段锁? 因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会

  • 深入理解Mysql的四种隔离级别

    一.首先什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交.如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作. 二.事务的 ACID 事务具有四个特征:原子性( Atomicity ).一致性( Consistency ).隔离性( Isolation )和持续性( Dura

  • mysql 详解隔离级别操作过程(cmd)

    读未提交示例操作过程-Read uncommitted 1.打开两个MySql的命令提示行,均进入相同数据库,并检查当前表内容为相同数据如下: 2.在A.B两端执行select @@tx_isolation;检查当前默认的隔离级别别,可以发现都是 Repeatable Read –可重复读-(在当前事务内,重复读取第一次读取过的数据就叫可重复读.) 3.修改A端的隔离级别为readuncommitted –读未提交.意思是可以读取别人没有提交的数据. set transactionisolati

  • 浅析MYSQL REPEATABLE-READ隔离级别

    REPEATABLE-READ 即可重复读,set autocommit= 0或者START TRANSACTION状态下select表的内容不会改变.这种隔离级别可能导致读到的东西是已经修改过的. 比如: 回话一中读取一个字段一行a=1 在回话二里这个字段该行修改a=0,并且提交 回话一中再update这个字段a=0,会发现受影响行数是0,这样就可以根据受影响行数是0还是1判断此次修改是否成功! 这在某些程序里会很有用! 会话1: mysql> set autocommit=0; Query

  • MySQL数据库事务隔离级别详解

    数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为 Read uncommitted:允许脏读. Read committed: 防止脏读,最常用的隔离级别,并且是大多数数据库的默认隔离级别. Repeatable read:可以防止脏读和不可重复读. Serializable:可以防止脏读,不可重复读取和幻读,(事务串行化)会降低数据库的效率. 这四个级别可以逐个解决脏读 .不可重复读 .幻读 这几类问题. √: 可能出现 ×: 不会出现 事务级别 脏读 不可重复读 幻读 Read

  • MySQL 四种事务隔离级别详解及对比

    MySQL 四种事务隔离级别详解及对比 按照SQL:1992 事务隔离级别,InnoDB默认是可重复读的(REPEATABLE READ).MySQL/InnoDB 提供SQL标准所描述的所有四个事务隔离级别.你可以在命令行用--transaction-isolation选项,或在选项文件里,为所有连接设置默认隔离级别. 例如,你可以在my.inf文件的[mysqld]节里类似如下设置该选项: transaction-isolation = {READ-UNCOMMITTED | READ-CO

  • mysql+Spring数据库隔离级别与性能分析

    这里以mysql为例,先明确以下几个问题: 一.一般项目如果不自己配置事务的话,一般默认的是autocommit,即执行完一个操作后自动commit,提交事务. (注:事务是绑定在数据库操作上的,也就是当程序执行(statement.excute等操作)转而到数据库层面上的时候,事务才开始发生)当然spring可以将几个数据库操作动作绑在一个事务中,这样就需要介绍下spring事务配置方法,下面介绍的是常用方法,其他方法网上有很多.spring提供了很多事务配置的策略,很方便,简要介绍一下: 复

  • MySQL四种事务隔离级别详解

    本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样.也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位. 2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 .比如A向B转账,不可能A扣了钱,

  • MySQL数据库事务隔离级别介绍(Transaction Isolation Level)

    数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 复制代码 代码如下: #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. [mysqld] transaction-isolation = REPEATABLE-READ 这里全局默认是REPEATABLE-READ,其实MySQL本来默认也是这个级别

  • 简述MySql四种事务隔离级别

    隔离级别: 隔离性其实比想象的要复杂. 在SQL标准中定义了四种隔离级别, 每一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的.较低级别的隔离通常可以执行更高的并发,系统的开销也更低. 下面简单地介绍一下四种隔离级别. 1.READ UNCOMMITTED(未提交读) 在 READ UNCOMMITTED级别, 事务中的修改, 即使没有提交, 对其他事务也都是可见的. 事务可以读取未提交的数据, 这也被称为脏读 (Dirty Read). 这个级别会导致很多问题,从性能上来说,

  • 通过实例分析MySQL中的四种事务隔离级别

    前言 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别.数据库事务的隔离级别有4个,下面话不多说了,来一起看看详细的介绍吧. 数据库事务有四种隔离级别: 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据. 提交读(Read Committed):只能读取到已经提交的数据,Oracle等多数数据库默认都是该级别. 可重复读(Repeated Read):可重复读.在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级

  • 一文了解MySQL事务隔离级别

    目录 前言 1.四种事务隔离级别 1.1 READ UNCOMMITTED 1.2 READ COMMITTED 1.3 REPEATABLE READ 1.4 SERIALIZABLE 1.5 小结 2.并发事务中的问题 2.1 脏读 2.2 不可重复读 2.3 幻读 3.隔离级别实战 3.1 查询事务隔离级别 3.2 设置事务隔离级别 3.3 脏读问题 3.4 不可重复读问题 3.5 幻读问题 总结 前言 MySQL 事务隔离级别是为了解决并发事务互相干扰的问题的,MySQL 事务隔离级别总

  • Mysql案例刨析事务隔离级别

    目录 1. 理论 SERIALIZABLE REPEATABLE READ READ COMMITTED READ UNCOMMITTED 2. SQL 实践 2.1 查看隔离级别 2.2 READ UNCOMMITTED 2.2.1 准备测试数据 2.2.2 脏读 2.2.3 不可重复读 2.2.4 幻象读 2.3 READ COMMITTED 2.4 REPEATABLE READ 2.5 SERIALIZABLE 3. 总结 很多小伙伴对 MySQL 的隔离级别一直心存疑惑,其实这个问题一

  • ORACLE数据库事务隔离级别介绍

    两个并发事务同时访问数据库表相同的行时,可能存在以下三个问题: 1.幻想读:事务T1读取一条指定where条件的语句,返回结果集.此时事务T2插入一行新记录,恰好满足T1的where条件.然后T1使用相同的条件再次查询,结果集中可以看到T2插入的记录,这条新纪录就是幻想. 2.不可重复读取:事务T1读取一行记录,紧接着事务T2修改了T1刚刚读取的记录,然后T1再次查询,发现与第一次读取的记录不同,这称为不可重复读. 3.脏读:事务T1更新了一行记录,还未提交所做的修改,这个T2读取了更新后的数据

随机推荐