並行效果

使用者修改資料會影響到同時正在讀取或修改相同資料的其他使用者。而我們就稱這些使用者正在並行地存取資料。若資料儲存系統沒有並行控制功能,使用者會看到下列副作用:

  • 更新遺失

  • 未認可依存性 (中途讀取)

  • 分析不一致 (不可重複讀取)

  • 幽靈讀取

  • 資料列更新造成遺漏讀取和重複讀取

更新遺失

如果二或多個交易選取相同資料列,接著又根據原先選取的值來更新資料列時,就會發生更新遺失的情形。每個交易並不知道有其他的交易存在。因此最後的更新會覆寫其他交易所做的更新,而造成資料遺失。

例如,兩位編輯人員對同一份文件製作了電子副本。這兩位編輯人員各自進行修改並儲存變更後的副本,覆寫了原始文件。最後儲存已變更副本的編輯人員會覆寫前一位編輯人員所做的變更。若第一位編輯人員完成和認可交易後才讓第二位編輯人員存取檔案的話,就能避免這個問題。

未認可依存性 (中途讀取)

第二筆交易選擇的資料列已經被其他交易更新時,會發生未認可依存性 (Uncommitted Dependency)。此時,第二筆交易讀取的是尚未認可且可能被更新資料列的交易變更之資料。

例如,有一位編輯人員正在修改一份電子文件。進行變更時,第二位編輯人員複製了包含目前所有變更的文件,並將文件散發給預期的讀者。此時,第一位編輯人員認為截至目前的變更均有誤,所以移除了原先的變更後儲存文件。散發的文件包含了一些現在已不存在的修改內容,而且這些修改應該視為從未發生過。如果能在第一位編輯人員儲存最後修改並認可交易後才允許其他人讀取修改過的文件,即可避免這個問題。

分析不一致 (不可重複讀取)

第二筆交易存取同一資料列數次,且每次讀取的資料內容都有變動時,就會產生不一致分析 (Inconsistent Analysis)。不一致分析的情況是第一筆交易在變更資料時,第二筆交易卻在讀取這些資料,其發生原理與未認可依存性類似。但是在不一致分析中,第二筆交易讀取的資料是由進行變更的交易認可。此外,不一致分析包括同一資料列的多次讀取 (兩次或以上),且每次資訊均被其他交易變更,因此稱為不可重複讀取 (Nonrepeatable Read)。

例如,一位編輯人員兩次都讀取了相同的文件,但是在兩次讀取期間寫作人員重寫了文件。因此在編輯者第二次讀取文件時,文件已經變更。而原始讀取是不可重複的。若能在編輯人員讀完文件後才讓寫作人員變更,就能避免這個問題。

幽靈讀取

如果您在交易讀取某範圍資料列中的一個資料列上執行插入或刪除作業時,就會產生幽靈讀取 (Phantom Read)。位於交易第一次讀取範圍內的資料列如果被其他的交易刪除,就不會出現在第二個與後續的讀取中。同樣地,其他交易執行插入作業後,交易的第二或後續讀取中顯示有一個資料列不屬於原始讀取。

例如,有一位編輯人員修改某作者送出的文件,但是生產部門將修改併入文件正本時,發現作者又加入未編輯的新內容。與不可重複讀取狀況類似,如果規定編輯人員和生產部門修改完原始文件後才可以新增文件內容,就可以避免這個問題。

資料列更新造成遺漏讀取和重複讀取

  • 遺漏更新的資料列或多次看到更新的資料列

    執行 READ UNCOMMITTED 等級的交易不會發出共用鎖定來防止其他交易修改目前交易所讀取的資料。執行 READ COMMITTED 等級的交易則會發出共用鎖定,但是在讀取資料列後,就會解除資料列或頁面的鎖定。在以上任一種情況下,當您掃描索引時,如果其他使用者變更了您讀取期間之資料列的索引鍵資料行,在索引鍵變更將資料列移到掃描前的任何位置後,該資料列可能會再次出現。同樣地,如果索引鍵變更將資料列移到您已經讀取之索引中的位置,該資料列可能就不會出現。若要避免這個情況發生,請使用 SERIALIZABLE 或 HOLDLOCK 提示,或資料列版本控制。如需詳細資訊,請參閱<資料表提示 (Transact-SQL)>和<Database Engine 中資料列版本控制式的隔離等級>。

  • 遺失一或多個非更新目標的資料列

    當您正在使用 READ UNCOMMITTED 時,如果您的查詢使用配置順序掃描 (使用 IAM 頁面) 讀取資料列,您可能會因為其他交易造成頁面分割而遺失資料列。當您使用認可的讀取時,不會發生這個狀況,因為頁面分割期間會將資料表保持在鎖定狀態下,而且,如果資料表沒有叢集索引,也不會發生這個狀況,因為更新不會造成頁面分割。