讀取已送出的快照,讀取過時的數據?
我正在執行 SQL Azure,我有以下案例。
我有兩個事務
W
(作者)和R
(讀者)。兩者都使用 RCSI(帶有使用 LTM 的 TransactionScopes 的.net 應用程序)執行。事務R
同時啟動W
並不斷執行 SELECT 語句以讀取由事務寫入的表W
。通常,事務在送出其更改
R
後會立即看到所有更改。W
但是,有時事務會R
看到沒有來自事務的最新送出的狀態W
。問題是:
RCSI 是否保證
R
始終看到表的最新狀態?根據: https ://docs.microsoft.com/en-us/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server- 2017 應始終閱讀已送出獲取執行SELECT
查詢時可用的行的最新版本。但是,當有兩個獨立的會話時,它可以保證嗎?
已送出的讀取應始終獲取在執行 SELECT 查詢時可用的行的最新版本。
是的,你是對的。由於它是 RCSI,它處於語句級別,而不是正常快照隔離的事務級別。
但是,當有兩個獨立的會話時,它可以保證嗎?
是的,應該是。
RCSI 是否保證
R
始終看到表的最新狀態?是的,從語句開始時開始,它將是最新的,並且如果需要,將基於版本儲存。這意味著如果讀取查詢開始並且寫入在寫入中間,則讀取語句將看到較舊的值。
您所描述的內容是正常的,並且符合一個執行緒上的小型、快速、並發更新並在另一個執行緒上讀取。大多數情況下,RCSI 以可能略微陳舊的讀取為代價來減輕鎖定/阻塞。您可以通過在每個語句開始、送出等時檢查單個語句級別來找到問題的根源,但是如果它們相隔幾毫秒或幾微秒,那麼除了寫入之外,您真的無法更改它訪問數據的應用程序的執行緒同步 - 從而強制讀取不會過時。
請注意,這假設寫入小、快且成功完成。例如,應用程序掛起且從不送出的寫入將在通過 RCSI 讀取時顯示先前的值,而不是保持阻塞狀態,例如在已送出的讀取中。