首頁  >  文章  >  php教程  >  Mysql 交易的四種隔離級別

Mysql 交易的四種隔離級別

WBOY
WBOY原創
2016-08-04 08:56:161079瀏覽

開發工作中我們會使用到事務,那你們知道事務又分哪幾種嗎?
MYSQL標準定義了4類隔離級別,用來限定事務內外的哪些改變是可見的,哪些是不可見的。
低的隔離級一般支援更高的並發處理,並擁有更低的系統開銷。
隔離等級由低到高:Read Uncommitted Read Uncommitted(讀取未提交內容)

在該隔離級別,所有交易都可以看到其他未提交(commit)事務的執行結果。
本隔離等級很少用於實際應用,因為它的效能也不比其他等級好多少。
讀取未提交的數據,也稱為髒讀(Dirty Read)。 [窗口A]:<br> <br> mysql> set GLOBAL tx_isolation='READ-UNCOMMITTED';<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登入)<br> <br> mysql> SELECT @@tx_isolation;<br> +------------------+<br> | @@tx_isolation   |<br> +------------------+<br> | READ-UNCOMMITTED |<br> +------------------+<br> 1 row in set (0.00 sec)<br> <br> mysql> use test;<br> Database changed<br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> select * from user;<br> +----+------+<br> | id | name |<br> +----+------+<br> |  1 | a    |<br> |  2 | b    |<br> +----+------+<br> 2 rows in set (0.00 sec)<br> <br> [視窗B]:<br> mysql> select @@tx_isolation;<br> +------------------+<br> | @@tx_isolation   |<br> +------------------+<br> | READ-UNCOMMITTED |<br> +------------------+<br> 1 row in set (0.00 sec)<br> <br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> insert into test.user values (3, 'c');<br> Query OK, 1 row affected (0.00 sec)<br> <br> mysql> select * from user;<br> +----+------+<br> | id | name |<br> +----+------+<br> |  1 | a    |<br> |  2 | b    |<br> |  3 | c    |<br> +----+------+<br> 3 rows in set (0.00 sec)<br> <br> //目前為止,視窗B並未commit;<br> <br> [窗口A]:<br> mysql> select * from user ;<br> +----+------+<br> | id | name |<br> +----+------+<br> |  1 | a    |<br> |  2 | b    |<br> |  3 | c    |<br> +----+------+<br> 3 rows in set (0.00 sec)Read Committed(讀取提交內容)

這是大多數資料庫系統的預設隔離等級(但不是MySQL預設的)。
它滿足了隔離的簡單定義:一個交易只能看見已經提交事務所所做的改變。
這種隔離等級 也支援所謂的不可重複讀取(NonrepeatableRead),因為相同交易的其他實例在該實例處理其間可能會有新的commit,所以相同 select 可能會傳回不同結果。 [窗口A]:<br> <br> mysql> SET GLOBAL tx_isolation='READ-COMMITTED';<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登入)<br> <br> mysql> SELECT @@tx_isolation;<br> +----------------+<br> | @@tx_isolation |<br> +----------------+<br> | READ-COMMITTED |<br> +----------------+<br> 1 row in set (0.00 sec)<br> <br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> select * from test.user;<br> +----+------+<br> | id | name |<br> +----+------+<br> |  1 | a    |<br> |  2 | b    |<br> +----+------+<br> 2 rows in set (0.00 sec)<br> <br> <br> [視窗B]:<br> <br> mysql> SELECT @@tx_isolation;<br> +----------------+<br> | @@tx_isolation |<br> +----------------+<br> | READ-COMMITTED |<br> +----------------+<br> 1 row in set (0.00 sec)<br> <br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br>mysql> 從 test.user 中選擇 *;<br> +----+------+<br> | 編號| 名字|<br> +----+------+<br> |  1 | 一個    |<br> |  2|| b    |<br> +----+------+<br> 2 行一組(0.00 秒)<br> <br> mysql> 從 test.user 中刪除,其中 id=1;<br> 查詢正常,1 行受影響(0.00 秒)<br> <br> mysql> 從 test.user 中選擇 *;<br> +----+------+<br> | 編號| 名字|<br> +----+------+<br> |  2|| b    |<br> +----+------+<br> 一組 1 行(0.00 秒)<br> <br> [窗口A]:<br> <br> mysql> 從 test.user 中選擇 *;<br> +----+------+<br> | 編號| 名字|<br> +----+------+<br> |  1| 一個    |<br> |  2|| b    |<br> +----+------+<br> 2 行一組(0.00 秒)<br> <br> [窗口B]:<br> <br> mysql> 提交;<br> 查詢正常,0 行受影響(0.02 秒)<br> <br> [窗口A]:<br> <br> mysql> 從 test.user 中選擇 *;<br> +----+------+<br> | 編號| 名字|<br> +----+------+<br> |  2|| b    |<br> +----+------+<br> 一組中 1 行(0.00 秒)可重複讀取(可重讀)

這是MySQL的預設事務隔離級別,它確保相同事務的多個實例在讀取資料時,會看到相同的資料行。
從理論上講,這會導致另一個棘手的問題:幻讀(Phantom Read)。然而
簡單的說,幻讀指當使用者讀取該範圍的資料行時,另一個事務又在該範圍內插入了新行,使用者當再讀取該範圍的資料行時,會發現有新的「幻影”行。
InnoDB和Falcon儲存引擎透過多版本並發控制(MVCC,Multiversion Concurrency Control)機制解決了這個問題。 [窗口A]:<br> <br> mysql> SET GLOBAL tx_isolation='REPEATABLE-READ';<br> 查詢正常,0 行受影響(0.00 秒)<br> <br> mysql> 退出;<br> 再見<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登入)<br> <br> mysql> 選擇@@tx_isolation;<br> +----------------+<br> | @@tx_isolation  |<br> +----------------+<br> | 可重複閱讀|<br> +----------------+<br> 一組 1 行(0.00 秒)<br> <br> mysql> 開始;<br> 查詢正常,0 行受影響(0.00 秒)<br> <br> [窗口B]:<br> <br> mysql> 退出;<br> 再見<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登入)<br> <br> mysql> 選擇@@tx_isolation;<br> +----------------+<br> | @@tx_isolation  |<br> +----------------+<br> | 可重複閱讀|<br> +----------------+<br> 一組 1 行(0.00 秒)<br> <br> mysql> 插入 test.user 值 (4, 'd');<br> 查詢正常,1 行受影響(0.00 秒)<br> <br> mysql> 從 test.user 中選擇 *;<br> +----+------+<br> | 編號| 名字|<br> +----+------+<br> |  2|| b    |<br> |  4| d    |<br> +----+------+<br> 2 行一組(0.00 秒)<br> <br> [窗口A]:<br> <br> mysql> 從 test.user 中選擇 *;<br> +----+------+<br> | 編號| 名字|<br> +----+------+<br> |  2|| b    |<br> +----+------+<br> 1 行一組(0.00 秒)<br> <br> mysql> 提交;<br> 查詢正常,0 行受影響(0.00 秒)<br> <br> mysql> 從 test.user 中選擇 *;<br> +----+------+<br> | 編號| 名字|<br> +----+------+<br> |  2|| b    |<br> |  4| d    |<br> +----+------+<br> 2 rows in set (0.00 sec)Serialized(序列化執行)

這是的隔離級別,它透過強制最高事務排序,使得不可能相互衝突,從而解決幻讀問題。
簡言之,它是在每個讀取的資料行上加上共享鎖定。在這個級別,可能導致大量的超時現象和鎖定競爭。 [窗口A]:<br> <br> mysql> SET GLOBAL tx_isolation='SERIALIZABLE';<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登入)<br> <br> mysql> SELECT @@tx_isolation;<br> +----------------+<br> | @@tx_isolation |<br> +----------------+<br> | SERIALIZABLE   |<br> +----------------+<br> 1 row in set (0.00 sec)<br> <br> mysql> select * from test.user;<br> +----+------+<br> | id | name |<br> +----+------+<br> |  2 | b    |<br> |  4 | d    |<br> +----+------+<br> 2 rows in set (0.00 sec)<br> <br> mysql> begin;<br> Query OK, 0 rows affected (0.00 sec)<br> <br> mysql> insert into test.user values (5, 'e');<br> Query OK, 1 row affected (0.00 sec)<br> <br> [視窗B]:<br> <br> mysql> quit;<br> Bye<br> <br> [root@vagrant-centos65 ~]# mysql -uroot -pxxxx(重新登入)<br> <br> mysql> SELECT @@tx_isolation;<br> +----------------+<br> | @@tx_isolation |<br> +----------------+<br> | SERIALIZABLE   |<br> +----------------+<br> 1 row in set (0.00 sec)<br> <br> mysql> select * from test.user;<br> ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction<br> <br> [窗口A]:<br> <br> mysql> commit;<br> Query OK, 0 rows affected (0.01 sec)<br> <br> [視窗B]:<br> <br> mysql> mysql> select * from test.user;<br> +----+------+<br> | id | name |<br> +----+------+<br> |  2 | b    |<br> |  4 | d    |<br> |  5 | e    |<br> +----+------+<br> 3 rows in set (0.00 sec)Thank ~

資料來源:http://mp.weixin.qq.com/s?__biz=MjM5NDM4MDIwNw==&mid=2448834642&idx=1&sn=c02c5cc8ab0c1f29142ac8f8aa6b78aff#rd

更多【乾貨分享】,請關注我的個人訂閱號碼。
Mysql 交易的四種隔離級別

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn