MySQL中的事務隔離級別

SQL 標準用三個必須在並行的事務之間避免的現象定義了四個級別的事務隔離。 這些不希望發生的現象是: 

  • 髒讀(dirty reads)


一個事務讀取了另一個未提交的並行事務寫的數據。 

  • 不可重複讀(non-repeatable reads)


一個事務重新讀取前面讀取過的數據, 發現該數據已經被另一個已提交的事務修改過。 

  • 幻讀(phantom read)


一個事務重新執行一個查詢,返回一套符合查詢條件的行, 發現這些行因爲其他最近提交的事務而發生了改變。

 

SQL 事務隔離級別 

離級別  髒讀(Dirty Read)          不可重複讀(NonRepeatable Read) 幻讀(Phantom Read)
讀未提交(Read uncommitted) 可能 可能 可能
讀已提交(Read committed) 不可能 可能 可能
可重複讀(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能

 

在MySQL中默認事務隔離級別是可重複讀(Repeatable read).可通過SQL語句查詢:
查看InnoDB系統級別的事務隔離級別:

    mysql> SELECT @@global.tx_isolation;

結果:
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+
1 row in set (0.00 sec)

查看InnoDB會話級別的事務隔離級別:

  mysql> SELECT @@tx_isolation;

結果:
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)

修改事務隔離級別:

    mysql> set global transaction isolation level read committed;

    Query OK, 0 rows affected (0.00 sec)

    mysql> set session transaction isolation level read committed;

    Query OK, 0 rows affected (0.00 sec)

InnoDB的可重複讀隔離級別和其他數據庫的可重複讀是有區別的,不會造成幻象讀(phantom read),所謂幻象讀,就是同一個事務內,多次select,可以讀取到其他session insert並已經commit的數據。下面是一個小的測試,證明InnoDB的可重複讀隔離級別不會造成幻象讀。測試涉及兩個session,分別爲session 1和session 2,隔離級別都是repeateable read,關閉autocommit

    mysql> select @@tx_isolation;
  
    +-----------------+
    | @@tx_isolation  |
    +-----------------+
    | REPEATABLE-READ |
    +-----------------+
    1 row in set (0.00 sec)
   
    mysql> set autocommit=off;

    Query OK, 0 rows affected (0.00 sec)

session 1 創建表並插入測試數據

     mysql> create table test(i int) engine=innodb;
    Query OK, 0 rows affected (0.00 sec)

    mysql> insert into test values(1);
    Query OK, 1 row affected (0.00 sec)

session 2 查詢,沒有數據,正常,session1沒有提交,不允許髒讀
     mysql> select * from test;
     Empty set (0.00 sec)

session 1 提交事務

    mysql> commit;
    Query OK, 0 rows affected (0.00 sec)

session 2 查詢,還是沒有數據,沒有產生幻象讀
                        
    mysql> select * from test;
    Empty set (0.00 sec)
                        
                        
以上試驗版本:
                        
    mysql> select version();
    +-------------------------+
    | version()               |
    +-------------------------+
    | 5.0.37-community-nt-log |
    +-------------------------+
    1 row in set (0.00 sec)
發佈了18 篇原創文章 · 獲贊 3 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章