交易及其控制機制

交易

事務是對具有開始和結束的資料的操作序列。

事務是讀取和寫入操作的順序執行。 事務的結束可以是儲存變更(提交)或取消變更(回滾)。 就資料庫而言,事務由多個請求組成,這些請求被視為單一請求。

事務必須滿足 ACID 屬性

原子性。 交易要么完全完成,要么根本沒有完成。

一致性。 完成事務時,不得違反對資料施加的限制(例如資料庫中的約束)。 一致性意味著系統將從一種正確狀態轉移到另一種正確狀態。

隔離。 並行運行的事務不應相互影響,例如更改另一個事務使用的資料。 執行並行事務的結果應該與順序執行事務的結果相同。

可持續性。 一旦提交,更改就不應丟失。

交易日誌

日誌儲存事務所所做的更改,確保系統發生故障時資料的原子性和穩定性

日誌包含資料在交易變更之前和之後的值。 預寫日誌策略需要在開始之前新增有關先前值的日誌條目,並在交易完成後新增有關最終值的日誌條目。 如果系統突然停止,資料庫會以相反的順序讀取日誌並取消事務所所做的變更。 遇到中斷的事務後,資料庫會執行它並對日誌進行變更。 處於故障時的狀態,資料庫會以正向順序讀取日誌並傳回事務所所做的變更。 這樣,已經提交的事務的穩定性和被中斷的事務的原子性得以保留。

僅僅重新執行失敗的事務不足以恢復。

例子。 用戶的帳戶中有 500 美元,用戶決定從 ATM 提取。 兩項交易正在進行中。 第一個讀取餘額值,如果餘額中有足夠的資金,則會向用戶發放資金。 第二個從餘額中減去所需的金額。 假設系統崩潰,第一次操作失敗,但第二次操作失敗。 在這種情況下,我們無法在系統恢復到原始狀態且餘額為正的情況下向用戶重新發放資金。

絕緣等級

讀已提交

髒讀問題是一個事務可以讀取另一個事務的中間結果。

例子。 初始餘額值為 0 美元。 T1 為您的餘額加 50 美元。 T2 讀取餘額(50 美元)。 T1 放棄更改並退出。 T2 繼續執行,但餘額資料不正確。

解決方案是讀取固定資料(Read Comied),也就是禁止讀取事務改變的資料。 如果事務A更改了某組數據,那麼事務B在存取該數據時,將被迫等待事務A完成。

可重複讀取

遺失更新問題。 T1 在 T2 的變更之上儲存變更。

例子。 初始餘額值為 0 美元,兩筆交易同時補充餘額。 T1 和 T2 讀取餘額為 0 美元。 然後 T2 將 $200 加到 $0 上並儲存結果。 T1 將 $100 加到 $0 上並儲存結果。 最終結果是 100 美元,而不是 300 美元。

不可重複讀取問題。 重複讀取相同的資料會傳回不同的值。

例子。 T1 讀取餘額值為 0 美元。 T2 然後向餘額加 50 美元並結束。 T1再次讀取數據,發現與先前的結果有出入。

可重複讀取確保第二次讀取將傳回相同的結果。 在事務完成之前,一個事務讀取的資料不能在其他事務中更改。 如果事務A讀取了某組數據,那麼事務B在存取該數據時,將被迫等待事務A完成。

有序讀取(可序列化)

幻讀問題。 根據特定條件選擇資料的兩個查詢傳回不同的值。

例子。 T1 請求餘額大於 0 美元但小於 100 美元的所有用戶的數量。 T2 從餘額為 1 美元的用戶中扣除 101 美元。 T1 重新發出請求。

有序讀取(可序列化)。 事務完全按順序執行。 禁止更新或新增符合請求條款的記錄。 如果交易 A 已要求整個表的數據,則整個表將被凍結以供其他事務使用,直到交易 A 完成。

調度程式

設定並行事務期間執行操作的順序。

提供指定的隔離等級。 如果運算的結果不依賴它們的順序,那麼這樣的運算是可交換的(Permutable)。 讀取操作和對不同資料的操作是可交換的。 讀寫和寫-寫操作不可交換。 調度程序的任務是交錯並行事務執行的操作,使得執行結果相當於交易的順序執行。

控制並行作業的機制(並發控制)

樂觀是基於發現和解決衝突,悲觀是基於防止衝突發生。

在樂觀的方法中,多個使用者擁有可供使用的資料副本。 第一個完成編輯的人保存更改,而其他人必須合併更改。 樂觀演算法允許衝突發生,但係統必須從衝突中恢復。

採用悲觀方法,第一個捕獲資料的使用者會阻止其他人接收資料。 如果衝突很少,那麼選擇樂觀策略是明智的,因為它提供了更高層次的並發性。

鎖定

如果一個事務鎖定了數據,那麼其他事務在存取該數據時必須等待它被解鎖。

區塊可以覆蓋在資料庫、表格、行或屬性上。 共享鎖可以由多個事務對相同資料施加,允許所有事務(包括施加該資料的事務)讀取,禁止修改和獨佔捕獲。 獨佔鎖只能由一個事務施加,允許施加事務的任何操作,禁止其他事務的任何操作。

死鎖是指事務最終處於無限期持續的掛起狀態的情況。

例子。 第一個事務等待第二個事務捕獲的資料被釋放,而第二個事務等待第一個事務捕獲的資料被釋放。

死鎖問題的樂觀解決方案允許死鎖發生,但隨後透過回滾死鎖所涉及的事務之一來恢復系統。

以一定的時間間隔搜尋死鎖。 其中一種檢測方法是按時間,即如果事務完成時間過長,則認為發生了死鎖。 當發現死鎖時,其中一個事務將回滾,從而允許死鎖中涉及的其他事務完成。 受害者的選擇可以基於交易的價值或其資歷(Wait-Die 和 Wound-wait 方案)。

每筆交易 T 分配了時間戳 TS 包含交易的開始時間。

等等,死吧。

如果 TS(鈦) < TS(Tj),然後 Ti 等待,否則 Ti 回滾並以相同的時間戳重新開始。

如果新的事務已取得資源且較舊的事務請求相同的資源,則允許較舊的事務等待。 如果較舊的事務已取得資源,則請求該資源的較新的事務將被回滾。

傷口等待。

如果 TS(鈦) < TS(Tj),然後 Tj 回滾並以相同的時間戳記重新開始,否則 Ti 等待。

如果較新的事務已取得資源,而較舊的事務請求相同的資源,則較新的事務將被回溯。 如果較舊的事務已取得資源,則允許請求該資源的較新的事務等待。 基於優先順序的受害者選擇可以防止死鎖,但會回滾未發生死鎖的事務。 問題是事務可以回滾很多次,因為...... 較舊的事務可能會長時間持有該資源。

死鎖問題的悲觀解決方案不允許事務在存在死鎖風險時開始執行。

為了偵測死鎖,建立一個圖(等待圖,wait-for-graph),該圖的頂點是事務,邊從等待釋放資料的事務指向已經擷取該資料的事務。 如果圖有循環,則認為發生了死鎖。 建立等待圖,尤其是在分散式資料庫中,是一個昂貴的過程。

兩階段鎖定 - 透過在事務開始時佔用事務使用的所有資源並在事務結束時釋放它們來防止死鎖

所有阻塞操作必須先於第一個解鎖操作。 它有兩個階段 - 增長階段,在此期間握力積累,以及收縮階段,在此期間握力被釋放。 如果無法擷取其中一項資源,則交易重新開始。 事務可能無法取得所需的資源,例如,如果多個事務競爭相同的資源。

兩階段提交確保提交在所有資料庫副本上執行

每個資料庫將有關將要更改的資料的資訊輸入日誌並回應協調器 OK(投票階段)。 當每個人都回答「OK」後,協調員會發出一個訊號,要求每個人都做出承諾。 提交後,伺服器回應“OK”;如果至少有一個伺服器沒有回應“OK”,則協調器發送一個訊號以取消對所有伺服器的變更(完成階段)。

時間戳法

當嘗試存取較新事務涉及的資料時,較舊事務將回滾

每筆交易都會分配一個時間戳 TS 對應於執行的開始時間。 如果 Ti 超過 Tj,然後 TS(鈦) < TS(Tj).

當事務回滾時,它會被指派一個新的時間戳記。 每個資料對象 Q 涉及的交易被標記了兩個標籤。 W-TS(Q) — 成功完成記錄的最年輕交易的時間戳 Q. R-TS(Q) — 執行讀取記錄的最新事務的時間戳 Q.

交易時 T 請求讀取數據 Q 有兩種選擇。

如果 TS(T) < W-TS(Q),即資料被較年輕的事務更新,則該事務 T 復原.

如果 TS(T) >= W-TS(Q),然後執行讀取並且 R-TS(Q) 正在成長 MAX(R-TS(Q), TS(T)).

交易時 T 請求資料更改 Q 有兩種選擇。

如果 TS(T) < R-TS(Q),也就是說,資料已經被較年輕的事務讀取過,如果進行更改,就會產生衝突。 交易 T 復原.

如果 TS(T) < W-TS(Q),即事務嘗試覆寫較新的值,事務 T 被回滾。 在其他情況下,進行更改並 W-TS(Q) 變得平等 TS(T).

不需要昂貴的等待圖建構。 較舊的事務依賴較新的事務,因此等待圖中沒有循環。 不存在死鎖,因為事務不是等待而是立即回滾。 級聯回滾是可能的。 如果 Ti 滾走了,並且 Tj 我讀取了我更改的數據 Ti,然後 Tj 也應該回滾。 如果同時 Tj 如果已經發生了,那麼就會違反穩定原則。

級聯回滾的解決方案之一。 一個事務在最後完成所有寫入操作,其他事務必須等待該操作完成。 事務在讀取之前等待提交。

Thomas 寫入規則 - 時間戳方法的變體,其中較新事務更新的資料禁止被較舊事務覆蓋

交易 T 請求資料更改 Q。 如果 TS(T) < W-TS(Q),即事務嘗試覆寫較新的值,事務 T 不會像時間戳方法那樣回滾。

來源: www.habr.com

添加評論