当前位置: 代码迷 >> MySQL >> MySQL隔离级别
  详细解决方案

MySQL隔离级别

热度:93   发布时间:2016-05-05 17:03:19.0
MySQL隔离级别 .

事务具有ACID四种特性。

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

1.脏读

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

2.不可重复读

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

3.幻读

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

?

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

1.Read Uncommitted

2.Read Committed

3.Repeatable Read

4.Serializable

?

隔离解别脏读不可重复读幻读
Read UncommittedYYY
Read CommittedNYY
Repeatable(default)NNY
SerializableNNN

?

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

Mysql 版本号

?

[sql] view plaincopyprint?
  1. mysql>?select?version();??
  2. +------------+ ??
  3. |?version()??|??
  4. +------------+ ??
  5. |?5.1.52-log?|??
  6. +------------+ ??
  7. 1?row?in?set?(0.00?sec)??
mysql> select version();+------------+| version()  |+------------+| 5.1.52-log |+------------+1 row in set (0.00 sec)

?

?

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

[sql] view plaincopyprint?
  1. mysql>?select?@@global.tx_isolation,@@tx_isolation;??
  2. +-----------------------+-----------------+ ??
  3. |?@@global.tx_isolation?|?@@tx_isolation??|??
  4. +-----------------------+-----------------+ ??
  5. |?REPEATABLE-READ???????|?REPEATABLE-READ?|??
  6. +-----------------------+-----------------+ ??
  7. 1?row?in?set?(0.00?sec)??
mysql> select @@global.tx_isolation,@@tx_isolation;+-----------------------+-----------------+| @@global.tx_isolation | @@tx_isolation  |+-----------------------+-----------------+| REPEATABLE-READ       | REPEATABLE-READ |+-----------------------+-----------------+1 row in set (0.00 sec)


更改会话级的隔离级别

?

[sql] view plaincopyprint?
  1. Session?1:??
  2. mysql>?set?session?tx_isolation='read-uncommitted';??
  3. Query?OK,?0?rows?affected?(0.00?sec)??
  4. mysql>?select?@@global.tx_isolation,@@tx_isolation;??
  5. +-----------------------+------------------+ ??
  6. |?@@global.tx_isolation?|?@@tx_isolation???|??
  7. +-----------------------+------------------+ ??
  8. |?REPEATABLE-READ???????|?READ-UNCOMMITTED?|??
  9. +-----------------------+------------------+ ??
  10. 1?row?in?set?(0.00?sec)??
  11. ??
  12. ??
  13. Session?2:??
  14. mysql>?select?@@global.tx_isolation,?@@tx_isolation;??
  15. +-----------------------+-----------------+ ??
  16. |?@@global.tx_isolation?|?@@tx_isolation??|??
  17. +-----------------------+-----------------+ ??
  18. |?REPEATABLE-READ???????|?REPEATABLE-READ?|??
  19. +-----------------------+-----------------+ ??
  20. 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)


更改系统级的隔离级别

?

?

[sql] view plaincopyprint?
  1. Session?1:??
  2. mysql>?set?global?tx_isolation='read-uncommitted';??
  3. Query?OK,?0?rows?affected?(0.00?sec)??
  4. mysql>?select?@@global.tx_isolation,@@tx_isolation;??
  5. +-----------------------+------------------+ ??
  6. |?@@global.tx_isolation?|?@@tx_isolation???|??
  7. +-----------------------+------------------+ ??
  8. |?READ-UNCOMMITTED??????|?READ-UNCOMMITTED?|??
  9. +-----------------------+------------------+ ??
  10. 1?row?in?set?(0.00?sec)??
  11. ??
  12. Session?2:??
  13. mysql>?select?@@global.tx_isolation,?@@tx_isolation;??
  14. +-----------------------+-----------------+ ??
  15. |?@@global.tx_isolation?|?@@tx_isolation??|??
  16. +-----------------------+-----------------+ ??
  17. |?READ-UNCOMMITTED??????|?REPEATABLE-READ?|??
  18. +-----------------------+-----------------+ ??
  19. 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语句的自动提交

?

[sql] view plaincopyprint?
  1. mysql>?set?autocommit=off;??
  2. Query?OK,?0?rows?affected?(0.00?sec)??
mysql> set autocommit=off;Query OK, 0 rows affected (0.00 sec)

?

查看SQL语句自动提交是否关闭

?

[plain] view plaincopyprint?
  1. mysql>?show?variables?like?'autocommit';??
  2. +---------------+-------+??
  3. |?Variable_name?|?Value?|??
  4. +---------------+-------+??
  5. |?autocommit????|?OFF???|??
  6. +---------------+-------+??
  7. 1?row?in?set?(0.00?sec)??
mysql> show variables like 'autocommit';+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit    | OFF   |+---------------+-------+1 row in set (0.00 sec)


建立实验表

?

?

?

[sql] view plaincopyprint?
  1. mysql>?create?table?tao?(col1?tinyint?unsigned,?col2?varchar(20),?primary?key(col1));??
  2. Query?OK,?0?rows?affected?(0.08?sec)??
  3. ??
  4. mysql>?show?create?table?tao?\G;??
  5. ***************************?1.?row?***************************??
  6. ???????Table:?tao??
  7. Create?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??
  12. 1?row?in?set?(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: taoCreate Table: CREATE TABLE `tao` (  `col1` tinyint(3) unsigned NOT NULL DEFAULT '0',  `col2` varchar(20) DEFAULT NULL,  PRIMARY KEY (`col1`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)


演示脏读

?

?

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

?

[sql] view plaincopyprint?
  1. mysql>?set?global?tx_isolation='read-committed';??
  2. Query?OK,?0?rows?affected?(0.00?sec)??
  3. mysql>?set?session?tx_isolation='read-committed';??
  4. Query?OK,?0?rows?affected?(0.00?sec)??
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)


演示不可重复读

?

?

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

?

[sql] view plaincopyprint?
  1. mysql>?set?global?tx_isolation='repeatable-read';??
  2. Query?OK,?0?rows?affected?(0.00?sec)??
  3. ??
  4. mysql>?set?session?tx_isolation='repeatable-read';??
  5. Query?OK,?0?rows?affected?(0.00?sec)??
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)


幻读

?

?

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

?

[sql] view plaincopyprint?
  1. mysql>?set?global?tx_isolation='serializable';??
  2. Query?OK,?0?rows?affected?(0.00?sec)??
  3. ??
  4. mysql>?set?session?tx_isolation='serializable';??
  5. Query?OK,?0?rows?affected?(0.00?sec)??
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)


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

  相关解决方案