mysql 動態修改隔離級別的命令
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{
READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SERIALIZABLE
}
1:READ UNCOMMITTED
在這種隔離級別中,事務能看到其他事務未提交的結果,像這種讀到uncommitted的數據稱爲dirty read
如:
mysql--root@localhostnone) 06:47:49>>show variables like 'tx%';
+---------------+------------------+
| Variable_name | Value |
+---------------+------------------+
| tx_isolation | READ-UNCOMMITTED |
+---------------+------------------+
1 row in set (0.00 sec)
session A session B
start TRANSACTION; start TRANSACTION;
select * from t4 where i>45; select * from t4 where i>45;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 55 | 2 | | 55 | 2 |
| 46 | 2 | | 46 | 2 |
| 47 | 3 | | 47 | 3 |
| 48 | 2 | | 48 | 2 |
insert into t4 values (49,4),(49,4);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
select * from t4 where i>45;
+------+------+
| i | j |
+------+------+
| 55 | 2 |
| 46 | 2 |
| 47 | 3 |
| 48 | 2 |
| 49 | 4 |
| 49 | 4 |
+------+------+
6 rows in set (0.00 sec)
select * from t4 where i>45;
+------+------+
| i | j |
+------+------+
| 55 | 2 |
| 46 | 2 |
| 47 | 3 |
| 48 | 2 |
| 49 | 4 |
| 49 | 4 |
+------+------+
6 rows in set (0.00 sec)
commit;
很明顯,在session A 中,未提交事務修改的數據,在session B中也能顯示,這樣就是未提交讀隔離級別
2:READ COMMITTED
在這種隔離級別下,事務只能看到其他事務commit的數據,但是在這種級別下,會出現所謂的”不可重複讀“問題,即查詢前後,得到的數據不一樣
如:
mysql--root@localhostnone) 07:02:03>>show variables like 'tx%';
+---------------+----------------+
| Variable_name | Value |
+---------------+----------------+
| tx_isolation | READ-COMMITTED |
+---------------+----------------+
1 row in set (0.00 sec)
session A session B
select * from t4 where i=55; select * from t4 where i=55;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 55 | 2 | | 55 | 2 |
+------+------+ +------+------+
1 row in set (0.00 sec) 1 row in set (0.00 sec)
update t4 set j=4 where i=55;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
select * from t4 where i=55; select * from t4 where i=55;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 55 | 4 | | 55 | 2 |
+------+------+ +------+------+
1 row in set (0.00 sec) 1 row in set (0.00 sec)
在session B中是看不到未提交事務修改的數據
commit;
select * from t4 where i=55; select * from t4 where i=55;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 55 | 4 | | 55 | 4 |
+------+------+ +------+------+
1 row in set (0.00 sec) 1 row in set (0.00 sec)
當事務提交後,session B 就能看到修改的數據,這樣也就發生了上述所謂的“不可重複讀”問題
3:REPEATABLE READ
理論上講,該級別解決了READ COMMITTED級別的“不可重複讀”問題,但是還是會出現所謂的“幽靈讀”問題,何謂“幽靈讀”,當你通過一區間查詢時候,其他事務在這期間插入一條數據並提交,這樣你在次查詢時,會發現突然多出一行,這就是所謂的“幽靈行”,但是對於innodb跟
falcon,他們通過MVCC解決了這個問題,故對於innodb 跟 falcon,實現了名副其實的可重複讀
如:
show variables like 'tx%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
1)
session A session B
start TRANSACTION; start TRANSACTION;
select * from t4 where i=55; select * from t4 where i=55;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 55 | 4 | | 55 | 4 |
+------+------+ +------+------+
1 row in set (0.00 sec) 1 row in set (0.00 sec)
update t4 set j=6 where i=55;
commit;
select * from t4 where i=55; select * from t4 where i=55;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 55 | 6 | | 55 | 4 |
+------+------+ +------+------+
1 row in set (0.00 sec) 1 row in set (0.00 sec)
像這次就沒有出現上一級別中不可能重複讀問題
2)
session A session B
start TRANSACTION; start TRANSACTION;
select * from t4 where i>47 and i<55; select * from t4 where i>47 and i<55;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 48 | 2 | | 48 | 2 |
+------+------+ +------+------+
1 row in set (0.00 sec) 1 row in set (0.00 sec)
insert into t4 values (50,1);
commit;
select * from t4 where i>47 and i<55; select * from t4 where i>47 and i<55;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 48 | 2 | | 48 | 2 |
| 50 | 1 | +------+------+
+------+------+ 1 row in set (0.00 sec)
2 rows in set (0.00 sec)
commit;
select * from t4 where i>47 and i<55;
+------+------+
| i | j |
+------+------+
| 48 | 2 |
| 50 | 1 |
+------+------+
2 rows in set (0.00 sec)
像這樣,沒有出現幽靈讀問題,就是真正的可持續讀了,
4:SERIALIZABLE
最高級別,這一級別是強制事務順序執行,這樣就解決了以上可持續讀的問題,但是會出現大量的鎖等待與死鎖問題
1)
session A SESSION B
start TRANSACTION; start TRANSACTION;
insert into t4 values (52,4);
select * from t4 where i>48 and i<55;
等待中。。。。
commit
+------+------+
| i | j |
+------+------+
| 50 | 1 |
| 51 | 4 |
| 52 | 4 |
+------+------+
3 rows in set (6.05 se
2)
session A SESSION B
start TRANSACTION; start TRANSACTION;
select * from t4 where i>50 and i<55; select * from t4 where i>48 and i<55;
+------+------+ +------+------+
| i | j | | i | j |
+------+------+ +------+------+
| 51 | 4 | | 50 | 1 |
| 52 | 4 | | 51 | 4 |
+------+------+ | 52 | 4 |
2 rows in set (0.00 sec) +------+------+
3 rows in set (0.00 sec)
insert into t4 values (53,4);
等待中 如執行insert 則出現死鎖,
session B ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
如 執行commit; session A 中insert 執行
這就是在innodb下,四種隔離級別的具體分析了。很明顯,根據自己的需要選擇何時的隔離級別,對於提升系統性能也有莫大的幫助
轉自:mysql中四種隔離級別的具體分析
http://bbs.linuxtone.org/thread-4781-1-1.html