MySQL隔离级别

Wesley13
• 阅读 708

事务具有ACID四种特性。

但是Isolation并发可能引起如下问题:

1.脏读

允许读取到未提交的脏数据。

2.不可重复读

如果你在时间点T1读取了一些记录,在T2时再想重新读取一次同样的这些记录时,这些记录可能已经被改变、或者消失不见。

3.幻读

解决了不重复读,保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。但是,如果另一个事务同时提交了新数据,本事务再更新时,就会“惊奇的”发现了这些新数据,貌似之前读到的数据是“鬼影”一样的幻觉。

由ANSI/ISO定义的SQL-92标准定义的四种隔离级别

1.Read Uncommitted

2.Read Committed

3.Repeatable Read

4.Serializable

隔离解别

脏读

不可重复读

幻读

Read Uncommitted

Y

Y

Y

Read Committed

N

Y

Y

Repeatable(default)

N

N

Y

Serializable

N

N

N

下面用MySQL数据库做一些小实验

Mysql 版本号

mysql> select version();  
+------------+  
| version()  |  
+------------+  
| 5.1.52-log |  
+------------+  
1 row in set (0.00 sec)  

查看InnoDB存储引擎 系统级的隔离级别 和 会话级的隔离级别

mysql> select @@global.tx_isolation,@@tx_isolation;  
+-----------------------+-----------------+  
| @@global.tx_isolation | @@tx_isolation  |  
+-----------------------+-----------------+  
| REPEATABLE-READ       | REPEATABLE-READ |  
+-----------------------+-----------------+  
1 row in set (0.00 sec) 

更改会话级的隔离级别

Session 1:  
mysql> set session tx_isolation='read-uncommitted';  
Query OK, 0 rows affected (0.00 sec)  
mysql> select @@global.tx_isolation,@@tx_isolation;  
+-----------------------+------------------+  
| @@global.tx_isolation | @@tx_isolation   |  
+-----------------------+------------------+  
| REPEATABLE-READ       | READ-UNCOMMITTED |  
+-----------------------+------------------+  
1 row in set (0.00 sec)  
  
  
Session 2:  
mysql> select @@global.tx_isolation, @@tx_isolation;  
+-----------------------+-----------------+  
| @@global.tx_isolation | @@tx_isolation  |  
+-----------------------+-----------------+  
| REPEATABLE-READ       | REPEATABLE-READ |  
+-----------------------+-----------------+  
1 row in set (0.00 sec)  

更改系统级的隔离级别

Session 1:  
mysql> set global tx_isolation='read-uncommitted';  
Query OK, 0 rows affected (0.00 sec)  
mysql> select @@global.tx_isolation,@@tx_isolation;  
+-----------------------+------------------+  
| @@global.tx_isolation | @@tx_isolation   |  
+-----------------------+------------------+  
| READ-UNCOMMITTED      | READ-UNCOMMITTED |  
+-----------------------+------------------+  
1 row in set (0.00 sec)  
  
Session 2:  
mysql> select @@global.tx_isolation, @@tx_isolation;  
+-----------------------+-----------------+  
| @@global.tx_isolation | @@tx_isolation  |  
+-----------------------+-----------------+  
| READ-UNCOMMITTED      | REPEATABLE-READ |  
+-----------------------+-----------------+  
1 row in set (0.00 sec) 

关闭SQL语句的自动提交

mysql> set autocommit=off;  
Query OK, 0 rows affected (0.00 sec)  

建立实验表

mysql> create table tao (col1 tinyint unsigned, col2 varchar(20), primary key(col1));  
Query OK, 0 rows affected (0.08 sec)  
  
mysql> show create table tao \G;  
*************************** 1. row ***************************  
       Table: tao  
Create Table: CREATE TABLE `tao` (  
  `col1` tinyint(3) unsigned NOT NULL DEFAULT '0',  
  `col2` varchar(20) DEFAULT NULL,  
  PRIMARY KEY (`col1`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8  
1 row in set (0.00 sec) 

演示脏读

MySQL隔离级别

更改隔离级别为Read Committed后,不存在脏读的问题。

mysql> set global tx_isolation='read-committed';  
Query OK, 0 rows affected (0.00 sec)  
mysql> set session tx_isolation='read-committed';  
Query OK, 0 rows affected (0.00 sec)  

演示不可重复读

MySQL隔离级别

更改隔离级别为Repeatable Read后,不存在不可重复读的问题

mysql> set global tx_isolation='repeatable-read';  
Query OK, 0 rows affected (0.00 sec)  
  
mysql> set session tx_isolation='repeatable-read';  
Query OK, 0 rows affected (0.00 sec) 

幻读

MySQL隔离级别

更改隔离级别为完全串行化 Serializable 后,不存在幻读的问题。

mysql> set global tx_isolation='serializable';  
Query OK, 0 rows affected (0.00 sec)  
  
mysql> set session tx_isolation='serializable';  
Query OK, 0 rows affected (0.00 sec) 

在这种情况下,只允许一个事务在执行,其它事务必须等待这个事务执行完后才能执行。没有并发,只是单纯的串行。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
OMG!Java高级开发岗必问知识点
目录1.Mysql2.CHAR与VARCHAR的区别?3.能说下myisam和innodb的区别吗?4.你能说下事务的基本特性和隔离级别吗?5.并发问题脏读、不可重复读、幻读?6.事务的隔离级别?7.说说自增主键、UUID?8.mysql的约束分类?9.drop、delete与tru
Wesley13 Wesley13
3年前
mysql 事务隔离级别
1. MySQL事务隔离级别,默认是可重复读(repeatableread)事务隔离级别脏读不可重复读幻读读未提交(readuncommitted)是是是不可重复读(readcommitted)否是是可重复读(repeatableread)否否是串行化(serializable)
Wesley13 Wesley13
3年前
mysql事务隔离级别
ReadUncommitted(读取未提交内容)在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(DirtyRead)。ReadCommitted(读取提交内容)这是大多数数据库系统的默认隔离级别(但不是MySQL默
Wesley13 Wesley13
3年前
MySQL事务与锁
事务的隔离级别SQL标准定义的4个隔离级别为:READUNCOMMITED(未提交读)事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,也被称为脏读。这个级别是隔离级别中最低的,实际情况基本不用。READCOMMITED(提交读)事务从开始直到提交之前,所做的任何修
Stella981 Stella981
3年前
SSM框架(3):配置Spring的事务管理器,实现事务控制
 一、相关概念1、不可重复读和幻读的区别  很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。  如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但
Stella981 Stella981
3年前
Spring 支持的事务隔离级别
并发事务所导致的问题:    当同一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发执行时,可能会出现许多意外的问题并发事务所导致的问题可以分为下面三种类型:     脏读:对于两个事物T1,T2,T1 读取了已经被T2更新但还没有被提交的字段.之后,若T2回滚,T1读取的内容就是临时且无效的.
Wesley13 Wesley13
3年前
MySQL的可重复读级别能解决幻读吗
引言之前在深入了解数据库理论的时候,了解到事物的不同隔离级别可能存在的问题。为了更好的理解所以在MySQL数据库中测试复现这些问题。关于脏读和不可重复读在相应的隔离级别下都很容易的复现了。但是对于幻读,我发现在可重复读的隔离级别下没有出现,当时想到难道是MySQL对幻读做了什么处理?测试:创建一张测试用的表dept:CREAT
Easter79 Easter79
3年前
SSM框架(3):配置Spring的事务管理器,实现事务控制
 一、相关概念1、不可重复读和幻读的区别  很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。  如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但
Wesley13 Wesley13
3年前
Mysql事务隔离实现机制
今天我们来看看事务隔离的实现原理事务隔离隔离性与隔离级别当数据库上有多个事务同时执行的时候,就可能出现脏读(dirtyread)、不可重复读(nonrepeatableread)、幻读(phantomread)的问题,为了解决这些问题,就有了“隔离级别”的概念在谈隔离级别之前,你首先要知道,你隔离得越严实,效率就会