天天看點

MySQL隔離級别事務具有4個特征資料庫隔離級别檢視&設定資料庫隔離級别資料庫隔離級别以及産生的問題檢視&設定資料庫隔離級别

事務具有4個特征

  • Atomicity(原子性):一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢複(Rollback)到事務開始前的狀态,就像這個事務從來沒有執行過一樣。
  • Consistency(一緻性):在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精确度、串聯性以及後續資料庫可以自發性地完成預定的工作。
  • Isolation(隔離性):資料庫允許多個并發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導緻資料的不一緻。事務隔離分為不同級别,包括讀未送出(Read uncommitted)、讀送出(read committed)、可重複讀(repeatable read)和串行化(Serializable)。
  • Durability(持久性):事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丢失。

資料庫隔離級别

在标準SQL規範中,定義了4個事務隔離級别,不同的隔離級别對事務的處理不同

  1. 未送出讀 (READ_UNCOMMITTED)
  2. 送出讀 (READ_COMMITTED)
  3. 可重複讀 (REPEATABLE_READ)
  4. 可串行化 (SERIALIZABLE)

檢視&設定資料庫隔離級别

檢視資料庫目前隔離級别

mysql> show SESSION variables like '%isolation%';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.02 sec)
           

設定資料庫隔離級别

mysql> set SESSION transaction_isolation ='read-uncommitted';
Query OK, 0 rows affected (0.00 sec)

mysql> show SESSION variables like '%isolation%';
+-----------------------+------------------+
| Variable_name         | Value            |
+-----------------------+------------------+
| transaction_isolation | READ-UNCOMMITTED |
+-----------------------+------------------+
1 row in set (0.00 sec)
           

資料庫隔離級别以及産生的問題

隔離級别 是否出現第一類丢失更新 是否出現髒讀 是否出現不可重複讀 是否出現幻讀 是否出現第二類丢失更新
Read Uncommited
Read Commited
Repeatable Read
Serializable

第一類丢失更新

撤銷一個事務時, 把其他事務已經送出的更新資料覆寫(此情況在事務中不可能出現, 因為一個事務中修改時此記錄已加鎖, 必須等待此事務完成後另一個事務才可以繼續UPDATE)

髒讀

一個事務讀到另一個事務尚未送出的修改,就是髒讀。

不可重複讀

指的是一個事務内多次讀取同一個資料集合。在這個事務還沒有結束時,另一個事務對資料進行了DML操作,導緻第一個事務兩次讀取資料不一樣。

和髒讀的差別在于:髒讀讀取到的時未送出的資料,不可重複讀,讀取的是已經送出的内容。

一般來說不可重複讀是可以被接受的,本就是已經送出的資料,不會帶來很大的問題。

幻讀

幻讀,針對的是Insert操作。事務1讀取指定的where子句所傳回的一些行。然後,事務2插入一個新行,這個新行也滿足事務1使用的查詢where子句。然後事務1再次使用相同的查詢讀取行,但是現在它看到了事務2剛插入的行。

在快照讀的情況下,MySQL 通過 MVCC 來避免幻讀。

在目前讀的情況下,MySQL 通過 next-key 來避免幻讀。

第二類丢失更新

這是不可重複讀中的特例, 一個事務覆寫另一個事務已送出的更新資料

複現各種情況

未送出讀下的髒讀、幻讀、不可重複讀

MySQL隔離級别事務具有4個特征資料庫隔離級别檢視&設定資料庫隔離級别資料庫隔離級别以及産生的問題檢視&設定資料庫隔離級别

送出讀下的髒讀、幻讀、不可重複讀

MySQL隔離級别事務具有4個特征資料庫隔離級别檢視&設定資料庫隔離級别資料庫隔離級别以及産生的問題檢視&設定資料庫隔離級别

可重複讀下的髒讀、幻讀、不可重複讀

MySQL隔離級别事務具有4個特征資料庫隔離級别檢視&設定資料庫隔離級别資料庫隔離級别以及産生的問題檢視&設定資料庫隔離級别

檢視&設定資料庫隔離級别

檢視資料庫目前隔離級别

mysql> show SESSION variables like '%isolation%';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.02 sec)
           

繼續閱讀