MySQL 的 事務和隔離級別
事務是一組原子性的SQL查詢,事務內的SQL語句,要么全部執行成功,要么全部執行失敗。本節重點介紹事務的ACID和隔離級別。
1. ACID
提到事務,大家肯定都不陌生,和數據庫打交道,我們都會用到事務。銀行轉賬是解釋事務的一個經典例子。銀行數據庫通常會有兩張表:支票表和儲蓄表?,F在要從用戶 A 的支票賬戶轉賬 100 元人民幣到儲蓄賬戶,一般是下面三個步驟:
- 檢查支票賬戶的余額高于 100 元;
- 從支票賬戶余額減去 100 元;
- 在儲蓄賬戶余額增加 100 元;
相應的 SQL 語句如下:
start transaction
select balance from checking where customer_name = 'A'
update checking set balance = balance - 100.00 where customer_name = 'A'
update savings set balance = balance + 100.00 where customer_name = 'A'
commit;
這三個步驟需要封裝成一個事務,任何一個步驟失敗,都必須回滾所有的步驟。簡單的說,事務就是保證一組數據庫操作,要么全部執行成功,要么全部執行失敗。
一個優秀的事務處理機制,需要具備 ACID 特性,即原子性(atomicity)、一致性(consistency)、隔離性(isolation)、持久性(durability)。
-
原子性(atomicity):一個事務被視為一個完整的最小工作單元,事務中的數據庫操作,要么全部執行成功,要么全部執行失敗回滾,不能只成功執行了其中的一部分數據庫操作;
-
一致性(consistency):數據庫總是從一個一致性的狀態轉換到另一個一致性的狀態。在銀行轉賬的例子中,即使執行到第四條 SQL 語句時失敗,用戶的支票賬戶也不會損失 100 元人民幣,因為執行失敗時,事務進行了回滾,所做的修改并沒有保存到數據庫中;
-
隔離性(isolation):通常來說,一個事物所做的修改在提交以前,對其他事務是不可見的。在銀行轉賬的例子中,當執行完第三條 SQL 語句時,此時另外一個程序在匯總支票賬戶,它所查詢到的用戶A的支票賬戶,并沒有減去 100 元人民幣;
-
持久性(durability):事務提交成功,所做的修改就會永久保存到數據庫中,即使系統崩潰,修改的數據也不會丟失。
在 MySQL 中,事務是在存儲引擎層實現的。MySQL 是支持多種存儲引擎的數據庫,但并不是所有的存儲引擎都支持事務,比如 MyISAM 就不支持事務。
事務增加了數據庫的安全性,同時也需要數據庫做很多額外的工作。相比沒有實現 ACID 的數據庫,實現了 ACID 的數據庫需要更強的 CPU、內存、以及磁盤空間。
2. 隔離級別
在 SQL 標準中,包含了四種隔離級別,即未提交讀(read uncommitted)、提交讀(read committed)、可重復讀(repeatable read)、可串行化(serializable)。
-
未提交讀(read uncommitted):一個事務還未提交,它所做的變更能被別的事務看到。事務可以讀取未提交的數據,被稱為臟讀(dirty read),這種隔離級別在實際應用中一般很少使用;
-
提交讀(read committed):一個事務提交之后,它所做的變更才能被別的事務看到。大多數數據庫的默認隔離級別是提交讀(read committed),比如 Oracle;
-
可重復讀(repeatable read):一個事務在執行過程中看到的數據,總是跟這個事務在啟動時看到的數據是一致的。在可重復讀隔離級別下,未提交變更對其他事務也是不可見的。該級別保證了在同一個事務中,多次讀取同樣記錄的結果是一致的。MySQL 的默認事務隔離級別是可重復讀(repeatable read);
-
可串行化(serializable):serializable 是最高的隔離級別。對同一行數據,讀寫都會進行加鎖。當出現鎖沖突時,后面訪問的事務必須等前一個事務完成,才能繼續執行。實際應用場景很少用到這種隔離級別,只有在非常需要確保數據一致性,而且可以接受沒有并發的情況,才會使用這種隔離級別。
下表為 ANSI SQL 隔離級別:
隔離級別 | 臟讀可能性 | 不可重復度可能性 | 幻讀可能性 | 加鎖讀 |
---|---|---|---|---|
未提交讀(read uncommitted) | yes | yes | yes | no |
提交讀(read committed) | no | yes | yes | no |
可重復讀(repeatable read) | no | no | yes | no |
可串行化(serializable) | no | no | no | yes |
3. 小結
本小節主要介紹了事務的 ACID 和隔離級別。
ACID特性:原子性(atomicity)、一致性(consistency)、隔離性(isolation)、持久性(durability)
隔離級別:未提交讀(read uncommitted)、提交讀(read committed)、可重復讀(repeatable read)、可串行化(serializable)