事務(wù)具有ACID四種特性。
但是Isolation并發(fā)可能引起如下問(wèn)題:
1.臟讀
允許讀取到未提交的臟數(shù)據(jù)。
2.不可重復(fù)讀
如果你在時(shí)間點(diǎn)T1讀取了一些記錄,在T2時(shí)再想重新讀取一次同樣的這些記錄時(shí),這些記錄可能已經(jīng)被改變、或者消失不見(jiàn)。
3.幻讀
解決了不重復(fù)讀,保證了同一個(gè)事務(wù)里,查詢的結(jié)果都是事務(wù)開(kāi)始時(shí)的狀態(tài)(一致性)。但是,如果另一個(gè)事務(wù)同時(shí)提交了新數(shù)據(jù),本事務(wù)再更新時(shí),就會(huì)“驚奇的”發(fā)現(xiàn)了這些新數(shù)據(jù),貌似之前讀到的數(shù)據(jù)是“鬼影”一樣的幻覺(jué)。
由ANSI/ISO定義的SQL-92標(biāo)準(zhǔn)定義的四種隔離級(jí)別
1.Read Uncommitted
2.Read Committed
3.Repeatable Read
4.Serializable
隔離解別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
Read Uncommitted | Y | Y | Y |
Read Committed | N | Y | Y |
Repeatable(default) | N | N | Y |
Serializable | N | N | N |
下面用Mysql數(shù)據(jù)庫(kù)做一些小實(shí)驗(yàn)
Mysql 版本號(hào)
- mysql> select version();
- +------------+
- | version() |
- +------------+
- | 5.1.52-log |
- +------------+
- 1 row in set (0.00 sec)
查看InnoDB存儲(chǔ)引擎 系統(tǒng)級(jí)的隔離級(jí)別 和 會(huì)話級(jí)的隔離級(jí)別
- mysql> select @@global.tx_isolation,@@tx_isolation;
- +-----------------------+-----------------+
- | @@global.tx_isolation | @@tx_isolation |
- +-----------------------+-----------------+
- | REPEATABLE-READ | REPEATABLE-READ |
- +-----------------------+-----------------+
- 1 row in set (0.00 sec)
更改會(huì)話級(jí)的隔離級(jí)別
- 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)
更改系統(tǒng)級(jí)的隔離級(jí)別
- 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)
關(guān)閉SQL語(yǔ)句的自動(dòng)提交
- mysql> set autocommit=off;
- Query OK, 0 rows affected (0.00 sec)
查看SQL語(yǔ)句自動(dòng)提交是否關(guān)閉
- mysql> show variables like 'autocommit';
- +---------------+-------+
- | Variable_name | Value |
- +---------------+-------+
- | autocommit | OFF |
- +---------------+-------+
- 1 row in set (0.00 sec)
建立實(shí)驗(yàn)表
- 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)
演示臟讀
更改隔離級(jí)別為Read Committed后,不存在臟讀的問(wèn)題。
- 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)
演示不可重復(fù)讀
更改隔離級(jí)別為Repeatable Read后,不存在不可重復(fù)讀的問(wèn)題。
- 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)
幻讀
更改隔離級(jí)別為完全串行化 Serializable 后,不存在幻讀的問(wèn)題。
- 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)
在這種情況下,只允許一個(gè)事務(wù)在執(zhí)行,其它事務(wù)必須等待這個(gè)事務(wù)執(zhí)行完后才能執(zhí)行。沒(méi)有并發(fā),只是單純的串行。