事务具有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 版本号
1mysql> select version(); 2+------------+ 3| version() | 4+------------+ 5| 5.1.52-log | 6+------------+ 71 row in set (0.00 sec)
查看InnoDB存储引擎 系统级的隔离级别 和 会话级的隔离级别
1mysql> select @@global.tx_isolation,@@tx_isolation; 2+-----------------------+-----------------+ 3| @@global.tx_isolation | @@tx_isolation | 4+-----------------------+-----------------+ 5| REPEATABLE-READ | REPEATABLE-READ | 6+-----------------------+-----------------+ 71 row in set (0.00 sec)
更改会话级的隔离级别
1Session 1: 2mysql> set session tx_isolation='read-uncommitted'; 3Query OK, 0 rows affected (0.00 sec) 4mysql> select @@global.tx_isolation,@@tx_isolation; 5+-----------------------+------------------+ 6| @@global.tx_isolation | @@tx_isolation | 7+-----------------------+------------------+ 8| REPEATABLE-READ | READ-UNCOMMITTED | 9+-----------------------+------------------+ 101 row in set (0.00 sec) 11 12 13Session 2: 14mysql> select @@global.tx_isolation, @@tx_isolation; 15+-----------------------+-----------------+ 16| @@global.tx_isolation | @@tx_isolation | 17+-----------------------+-----------------+ 18| REPEATABLE-READ | REPEATABLE-READ | 19+-----------------------+-----------------+ 201 row in set (0.00 sec)
更改系统级的隔离级别
1Session 1: 2mysql> set global tx_isolation='read-uncommitted'; 3Query OK, 0 rows affected (0.00 sec) 4mysql> select @@global.tx_isolation,@@tx_isolation; 5+-----------------------+------------------+ 6| @@global.tx_isolation | @@tx_isolation | 7+-----------------------+------------------+ 8| READ-UNCOMMITTED | READ-UNCOMMITTED | 9+-----------------------+------------------+ 101 row in set (0.00 sec) 11 12Session 2: 13mysql> select @@global.tx_isolation, @@tx_isolation; 14+-----------------------+-----------------+ 15| @@global.tx_isolation | @@tx_isolation | 16+-----------------------+-----------------+ 17| READ-UNCOMMITTED | REPEATABLE-READ | 18+-----------------------+-----------------+ 191 row in set (0.00 sec)
关闭SQL语句的自动提交
1mysql> set autocommit=off; 2Query OK, 0 rows affected (0.00 sec)
建立实验表
1mysql> create table tao (col1 tinyint unsigned, col2 varchar(20), primary key(col1)); 2Query OK, 0 rows affected (0.08 sec) 3 4mysql> show create table tao \G; 5*************************** 1. row *************************** 6 Table: tao 7Create Table: CREATE TABLE `tao` ( 8 `col1` tinyint(3) unsigned NOT NULL DEFAULT '0', 9 `col2` varchar(20) DEFAULT NULL, 10 PRIMARY KEY (`col1`) 11) ENGINE=InnoDB DEFAULT CHARSET=utf8 121 row in set (0.00 sec)
演示脏读

更改隔离级别为Read Committed后,不存在脏读的问题。
1mysql> set global tx_isolation='read-committed'; 2Query OK, 0 rows affected (0.00 sec) 3mysql> set session tx_isolation='read-committed'; 4Query OK, 0 rows affected (0.00 sec)
演示不可重复读

更改隔离级别为Repeatable Read后,不存在不可重复读的问题
1mysql> set global tx_isolation='repeatable-read'; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> set session tx_isolation='repeatable-read'; 5Query OK, 0 rows affected (0.00 sec)
幻读

更改隔离级别为完全串行化 Serializable 后,不存在幻读的问题。
1mysql> set global tx_isolation='serializable'; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> set session tx_isolation='serializable'; 5Query OK, 0 rows affected (0.00 sec)
在这种情况下,只允许一个事务在执行,其它事务必须等待这个事务执行完后才能执行。没有并发,只是单纯的串行。