事務詳解
概述
事務(Transaction)是由一系列對系統中資料進行訪問與更新的操作所組成的一個程式執行邏輯單元。
ACID 事務具有4個基本特徵,分別是:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、永續性(Duration),簡稱ACID。
隔離級別 ACID這4個特徵中,最難理解的是隔離性。在標準SQL規範中,定義了4個事務隔離級別,不同的隔離級別對事務的處理不同。4個隔離級別分別是:讀未提及(READ_UNCOMMITTED)、讀已提交(READ_COMMITTED)、可重複讀(REPEATABLE_READ)、順序讀(SERIALIZABLE)。
事務併發引起的問題 資料庫在不同的隔離性級別下併發訪問可能會出現以下幾種問題:髒讀(Dirty Read)、不可重複讀(Unrepeatable Read)、幻讀(Phantom Read)。
事務的思維導圖
ACID
1. 原子性(Atomicity)
事務的原子性是指事務必須是一個原子的操作序列單元。事務中包含的各項操作在一次執行過程中,只允許出現兩種狀態之一。
- 全部執行成功
- 全部執行失敗
任何一項操作都會導致整個事務的失敗,同時其它已經被執行的操作都將被撤銷並回滾,只有所有的操作全部成功,整個事務才算是成功完成。
2. 一致性(Consistency)
事務的一致性是指事務的執行不能破壞資料庫資料的完整性和一致性,一個事務在執行之前和執行之後,資料庫都必須處以一致性狀態。
比如:如果從A賬戶轉賬到B賬戶,不可能因為A賬戶扣了錢,而B賬戶沒有加錢。
3. 隔離性(Isolation)
事務的隔離性是指在併發環境中,併發的事務是互相隔離的,一個事務的執行不能被其它事務干擾。也就是說,不同的事務併發操作相同的資料時,每個事務都有各自完整的資料空間。
一個事務內部的操作及使用的資料對其它併發事務是隔離的,併發執行的各個事務是不能互相干擾的。
隔離性分4個級別,下面會介紹。
4. 永續性(Duration)
事務的永續性是指事務一旦提交後,資料庫中的資料必須被永久的儲存下來。即使伺服器系統崩潰或伺服器宕機等故障。只要資料庫重新啟動,那麼一定能夠將其恢復到事務成功結束後的狀態。
事務隔離級別
1. 讀未提及(READ_UNCOMMITTED)
讀未提及,該隔離級別允許髒讀取,其隔離級別是最低的。換句話說,如果一個事務正在處理某一資料,並對其進行了更新,但同時尚未完成事務,因此還沒有提交事務;而以此同時,允許另一個事務也能夠訪問該資料。
髒讀示例:
在事務A和事務B同時執行時可能會出現如下場景:
時間 | 事務A(存款) | 事務B(取款) |
---|---|---|
T1 | 開始事務 | —— |
T2 | —— | 開始事務 |
T3 | —— | 查詢餘額(1000元) |
T4 | —— | 取出1000元(餘額0元) |
T5 | 查詢餘額(0元) | —— |
T6 | —— | 撤銷事務(餘額恢復1000元) |
T7 | 存入500元(餘額500元) | —— |
T8 | 提交事務 | —— |
餘額應該為1500元才對。請看T5時間點,事務A此時查詢的餘額為0,這個資料就是髒資料,他是事務B造成的,很明顯是事務沒有進行隔離造成的。
2. 讀已提交(READ_COMMITTED)
讀已提交是不同的時候執行的時候只能獲取到已經提交的資料。 這樣就不會出現上面的髒讀的情況了。
不可重複讀示例
可是解決了髒讀問題,但是還是解決不了可重複讀問題。
時間 | 事務A(存款) | 事務B(取款) |
---|---|---|
T1 | 開始事務 | —— |
T2 | —— | 開始事務 |
T3 | —— | 查詢餘額(1000元) |
T4 | 查詢餘額(1000元) | —— |
T5 | —— | 取出1000元(餘額0元) |
T6 | —— | 提交事務 |
T7 | 查詢餘額(0元) | —— |
T8 | 提交事務 | —— |
事務A其實除了查詢兩次以外,其它什麼事情都沒做,結果錢就從1000程式設計0了,這就是不可重複讀的問題。
3. 可重複讀(REPEATABLE_READ)
可重複讀就是保證在事務處理過程中,多次讀取同一個資料時,該資料的值和事務開始時刻是一致的。因此該事務級別進位制了不可重複讀取和髒讀,但是有可能出現幻讀的資料。
幻讀
幻讀就是指同樣的事務操作,在前後兩個時間段內執行對同一個資料項的讀取,可能出現不一致的結果。
時間 | 事務A(統計總存款) | 事務B(存款) |
---|---|---|
T1 | 開始事務 | —— |
T2 | —— | 開始事務 |
T3 | 統計總存款(1000元) | —— |
T4 | —— | 存入100元 |
T5 | —— | 提交事務 |
T6 | 提交總存款(10100) | —— |
T7 | 提交事務 | —— |
銀行工作人員在一個事務中多次統計總存款時看到結果不一樣。如果要解決幻讀,那隻能使用順序讀了。
4. 順序讀(SERIALIZABLE)
順序讀是最嚴格的事務隔離級別。它要求所有的事務排隊順序執行,即事務只能一個接一個地處理,不能併發。
事務隔離級別對比
事務隔離級別 | 髒 讀 | 不可重複讀 | 幻 讀 |
---|---|---|---|
讀未提及(READ_UNCOMMITTED) | 允許 | 允許 | 允許 |
讀已提交(READ_COMMITTED) | 禁止 | 允許 | 允許 |
可重複讀(REPEATABLE_READ) | 禁止 | 禁止 | 允許 |
順序讀(SERIALIZABLE) | 禁止 | 禁止 | 禁止 |
4種事務隔離級別從上往下,級別越高,併發性越差,安全性就越來越高。 一般資料預設級別是讀以提交或可重複讀。