交易隔離層級(ODBC)

交易隔離等級 是衡量交易隔離成功程度的指標。 特別地,交易隔離層級由以下現象的存在或缺失所定義:

  • 髒讀髒讀是指在交易讀取尚未提交的資料時發生。 例如,假設交易 1 更新了一列。 交易 2 在交易 1 提交更新前讀取更新的列。 如果交易 1 回滾了變更,交易 2 將讀取了被視為從未存在的資料。

  • 不可重複讀取不可重複讀取是指交易重複讀取同一列兩次,但每次取得的資料不同。 例如,假設交易 1 讀取一列。 交易 2 更新或刪除該列,並提交更新或刪除。 如果交易 1 重讀該列,會取得不同的列值或發現該列已被刪除。

  • 幻影幻影是一列符合搜尋條件但最初未被看到的列。 例如,假設交易 1 讀取一組符合某些搜尋條件的列。 交易 2 會產生一列新資料列(透過更新或插入),符合交易 1 的搜尋條件。 如果交易 1 重新執行讀取列的語句,則會得到不同的列數。

四個交易隔離層級(依 SQL-92 定義)是根據這些現象來定義的。 在下表中,每個可能發生的現象都以「X」標示。

交易隔離層級 髒話 不可重複讀取 幻影
讀取未認可 X X X
讀取認可 -- X X
可重複讀取 -- -- X
可序列化 -- -- --

下表說明資料庫管理系統(DBMS)可能實現交易隔離層級的簡單方式。

這很重要

大多數資料庫管理系統(DBMS)使用比這些更複雜的方案來增加並行性。 以上範例僅供說明使用。 特別是,ODBC 並未規定特定資料庫管理系統(DBMS)如何彼此隔離交易。

交易隔離 可能的實作
讀取未認可 交易之間並非獨立。 如果資料庫管理系統支援其他交易隔離層級,它會忽略用來實作這些層級的機制。 為了不影響其他交易,執行於讀取未承諾層級的交易通常為唯讀。
讀取認可 交易會等待其他交易寫入鎖定的列被解鎖;這樣可以防止讀取任何「髒資料」。

交易會對目前資料列保留讀取鎖(若只讀取該列)或寫鎖(若更新或刪除該列),以防止其他交易更新或刪除該資料。 交易在離開當前列時會釋放讀取鎖。 它會保留寫入鎖,直到被提交或回滾。
可重複讀取 交易會等待其他交易寫入鎖定的列被解鎖;這樣可以防止讀取任何「髒資料」。

交易在返回應用程式的所有資料列上保留讀取鎖,並對插入、更新或刪除的所有資料列保持寫入鎖。 例如,如果交易包含 SQL 陳述式 SELECT * FROM Orders,在應用程式擷取列時,交易會對這些列進行讀取鎖定。 如果交易包含 SQL 語句 DELETE FROM Orders WHERE Status = 'CLOSED',那麼該交易會在刪除資料列時對其進行寫入鎖定。

由於其他交易無法更新或刪除這些列,目前的交易避免了不可重複的讀取。 交易在被提交或回滾時釋放鎖。
可序列化 交易會等待其他交易寫入鎖定的列被解鎖;這樣可以防止讀取任何「髒資料」。

交易會在其影響的資料列範圍內持有讀鎖(如果它僅讀取資料列)或寫鎖(如果它可以更新或刪除資料列)。 例如,若交易包含 SQL 陳述式 SELECT * FROM Orders,則範圍為整個 Orders 資料表;交易會對資料表進行讀鎖,且不允許插入任何新資料列。 若交易包含 DELETE FROM Orders WHEREStatus = 'CLOSED' 的 SQL 陳述式,則該範圍為所有狀態為「CLOSED」的列;該交易會將訂單資料表中所有狀態為「CLOSED」的列寫入鎖定,且不允許插入或更新任何列,使得產生的列的狀態為「CLOSED」。

由於其他交易無法更新或刪除該範圍內的列,目前的交易避免了任何不可重複的讀取。 由於其他交易無法在該範圍內插入任何列,目前的交易避免了任何幻影。 交易在被提交或回滾時釋放鎖。

值得注意的是,交易隔離層級不會影響交易看到自身變更的能力;交易隨時都能看到他們所做的任何變更。 例如,一筆交易可能包含兩個 UPDATE 報表,第一個將所有員工的薪資提高 10%,第二個則設定員工在某個最高薪額上的薪資上限為該金額。 此程序之所以能作為單一交易成功,乃是因為第二個 UPDATE 陳述式能看到第一個陳述式的結果。