1.1 簡介
現在樂趣開始了——交易如何運作的理論。當您在不同線程中更改相同數據時,如何保持系統正常工作?或者您想在另一筆交易中執行一筆交易?我們將開始通過研究事務的隔離性來尋找這些問題的答案……
事務隔離級別是一個條件值,它決定了由於 DBMS 中邏輯並行事務的執行,允許不一致數據的程度。事務隔離級別的規模包含許多值,從低到高排列;更高的隔離級別對應於更好的數據一致性,但它的使用可能會減少物理上並行事務的數量。
相反,較低的隔離級別允許更多並行事務,但會降低數據準確性。因此,選擇所使用的事務隔離級別,信息系統的開發人員在一定程度上提供了工作速度和確保從系統接收的數據的保證一致性之間的選擇。
使用事務並發訪問的問題
當事務並行執行時,可能會出現以下問題:
- 丟失更新——如果一個數據塊被不同的事務同時更改,則所有更改都將丟失,除了最後一個;
- “臟”讀(eng. Dirty read) ——讀取交易添加或更改的數據,隨後不會被確認(回滾);
- 不可重複讀(eng. non-repeatable read) ——當在同一個事務內重新讀取時,之前讀取的數據被改變;
- 幻讀- 一個事務在其執行期間多次根據相同的標準選擇許多行。在這些獲取之間的另一個事務添加行或修改第一個事務的獲取條件中使用的某些行的列並成功結束。結果,第一個事務中的相同選擇會給出不同的行集。
考慮可能發生這些問題的情況。
1.2 丟失更新
當一個數據塊被不同的事務同時更改時,其中一個更改丟失的情況。
假設有兩個事務同時運行:
事務 1 | 交易 2 |
---|---|
更新 tbl1 SET f2=f2+20 WHERE f1=1; | 更新 tbl1 SET f2=f2+25 WHERE f1=1; |
在這兩個事務中,f2 字段的值都發生了變化;完成後,該字段的值必須增加 45。實際上,可能會發生以下一系列操作:
- 兩個事務同時讀取字段的當前狀態。這裡不需要精確的物理並發,在另一個事務寫入其結果之前按順序完成第二次讀取操作就足夠了。
- 兩個事務都通過分別將先前讀取的值加上 20 和 25 來計算新的字段值。
- 事務嘗試將計算結果寫回字段 f2。由於物理上不可能同時執行兩次寫操作,因此實際上其中一個寫操作會先執行,另一個會晚執行。第二次寫操作將覆蓋第一次的結果。
這樣一來,f2字段的值,在兩個事務都完成後,可能不會增加45,而是增加20或25,也就是說,其中一個數據更改事務將“消失”。
1.3 “臟”讀
讀取由稍後將無法提交(回滾)的事務添加或修改的數據。
假設我們有兩個事務由執行以下 SQL 語句的不同應用程序打開:
事務 1 | 交易 2 |
---|---|
更新 tbl1 SET f2=f2+1 WHERE f1=1; | |
從 tbl1 中選擇 f2,其中 f1=1; | |
回滾工作; |
在事務1中,改變了字段f2的值,然後在事務2中,選擇了這個字段的值。之後事務1被回滾,結果第二個事務接收到的值會和數據庫中存儲的值不一樣。
1.4 不可重複讀
當在同一事務中重新讀取時,先前讀取的數據被更改的情況。
假設我們有兩個事務由執行以下 SQL 語句的不同應用程序打開:
事務 1 | 交易 2 |
---|---|
從 tbl1 中選擇 f2,其中 f1=1; | |
更新 tbl1 SET f2=f2+3 WHERE f1=1; | |
犯罪; | |
從 tbl1 中選擇 f2,其中 f1=1; |
在事務2中,選擇了字段f2的值,然後在事務1中,更改了字段f2的值。如果您再次嘗試從事務 2 中的字段 f2 中選擇一個值,將獲得不同的結果。當為了部分修改數據並將其寫回數據庫而讀取數據時,這種情況尤其不能接受。
1.5 閱讀“幻影”
在同一事務中重複讀取期間,同一選擇給出不同行集的情況。
假設有兩個事務被不同的應用打開,執行如下SQL語句:
事務 1 | 交易 2 |
---|---|
從 tbl1 中選擇總和 (f2); | |
插入 tbl1 (f1,f2) 值 (15,20); | |
犯罪; | |
從 tbl1 中選擇總和 (f2); |
事務2執行一條SQL語句,使用了字段f2的所有值。然後在事務1中插入了一個新行,導致事務2中的SQL語句重新執行產生了不同的結果。這種情況稱為幻讀(phantom reading)。它與不可重複讀的區別在於,重複訪問數據的結果發生變化不是因為數據本身的改變/刪除,而是因為新的(幻像)數據的出現。
GO TO FULL VERSION