Database-Design

可重複讀取:該事務可能相對於其他事務不可序列化

  • July 13, 2021

下面的文字來自’數據庫系統概念,Silberschatz。我看不懂加粗的部分。交易如何相對於其他交易不能序列化?還有一個事務如何找到由已送出事務插入的一些數據,但可能找不到由同一事務插入的其他數據?

可重複讀取只允許讀取已送出的數據,並進一步要求在事務對數據項的兩次讀取之間,不允許其他事務對其進行更新。但是,該事務可能不能相對於其他事務進行序列化。例如,在搜尋滿足某些條件的數據時,一個事務可能會找到一些已送出事務插入的數據,但可能找不到同一事務插入的其他數據。

這與隔離級別的概念有關。有關詳細資訊,請參閱https://en.wikipedia.org/wiki/Isolation_(database_systems)

隔離級別由以下一種或多種現象的存在(或不存在)定義:

  1. 臟讀

這意味著能夠查看未送出的數據:由另一個事務進行但尚未送出的更改。這在現實生活中很少見——很少有數據庫系統允許這樣做。這是有風險的,因為它可能返回不一致的數據。例如銀行轉賬:原始賬戶已借記,但目的賬戶尚未貸記。如果您的應用程序在兩次更新之間讀取賬戶,看起來錢已經消失了!

  1. 不可重複讀取

這就是你引用的那句話所說的。這意味著您可以看到其他事務已送出的更改。這意味著,如果您在事務中重複相同的查詢,您可能會得到不同的結果,因為有人可能已經更改了您之前讀取的數據。對於任何涉及在確認訂單之前檢查庫存的應用程序來說,這都是一個問題:應用程序發現庫存中有 5 個小玩意兒,然後為其中的 4 個小玩意兒下訂單——但與此同時,其他人已經訂購了它們。

可以通過對事務中讀取的所有內容設置讀取鎖來防止這種現象。這可以防止其他人在您閱讀數據時更新數據。這有點像你在商店櫥窗裡看一雙鞋,這個簡單的事實讓這雙鞋賣不出去。

  1. 幻讀

假設您確實在您閱讀的所有內容上都設置了讀鎖。這仍然不能保證您在重複閱讀時得到相同的答案:您首先閱讀的所有內容都是安全的:沒有人可以更新或刪除任何內容。然而,簡單的讀鎖不會阻止任何人插入新行。這可能導致報告不一致。假設您列印出包含詳細銷售額的銷售報告。然後你想列印總數,你可以通過另一個查詢來計算總數。這個總數可能與細節不符:那是因為當您閱讀各個行時,有人插入了新的銷售並送出了它。

防止幻像要困難得多:不可能在讀取的行上設置讀取鎖以防止更新:由於新行還不存在,因此沒有什麼可鎖定的。典型的技術是在整個表上放置鎖——這對於並發和有效的單執行緒插入非常不利。更好的技術涉及在索引節點上放置鎖,因為索引節點代表一個或多個行,有效地防止在某些應用程序讀取的行範圍內進行任何插入。

這三種現像用於描述隔離級別:

未送出讀是最低的隔離級別:基本上沒有一致性(允許臟讀)。

已送出讀只防止臟讀。讀取不可重複:重複相同的讀取可能會產生不同的結果

可重複讀取可防止不可重複讀取,但不能防止幻讀。讀取將返回與前一次執行相同的行 - 但它可能會返回更多行:這些行在第一次讀取時還不存在。

可序列化可防止幻讀。這是最高級別的一致性。它保證在一個事務中完成的所有讀取總是提供完全相同的結果。之所以稱為可串列化,是因為執行一系列並發事務的效果與按特定順序串列執行這些事務的效果相同。

引用自:https://dba.stackexchange.com/questions/283104