交易隔離等級 (ODBC)
交易隔離等級是交易隔離成功範圍的量值。 特別是,下列交易隔離等級會在存在或不存在下列現象時定義:
中途讀取:當交易讀取尚未認可的資料,就會發生中途讀取。 例如,假設交易 1 更新資料列。 交易 2 會先讀取更新的資料列,交易 1 才會認可更新。 如果交易 1 復原變更,則交易 2 將會讀取視為不存在的資料。
不可重複讀取:當交易讀取相同資料列兩次但每次取得不同的資料,就會發生不可重複讀取。 例如,假設交易 1 讀取資料列。 交易 2 會更新或刪除該資料列,並認可更新或刪除。 如果交易 1 會重新讀取資料列,則會擷取不同資料列值或發現資料列已刪除。
虛設項目:虛設項目是符合搜尋準則但一開時看不到的資料列。 例如,假設交易 1 讀取一組符合某些搜尋準則的資料列。 交易 2 會產生符合交易 1 搜尋準則的新資料列 (透過更新或插入)。 如果交易 1 重新執行讀取資料列的陳述式,則會取得一組不同的資料列。
四個交易隔離等級 (由 SQL-92 定義) 是根據下現象所定義。 在下表中,"X" 會標示可能發生的每個現象。
交易隔離等級 | 中途讀取 | 不可重複讀取 | 虛設項目 |
---|---|---|---|
讀取未認可 | X | X | X |
讀取認可 | -- | X | X |
可重複讀取 | -- | -- | X |
可序列化 | -- | -- | -- |
下表說明 DBMS 可能實作交易隔離等級的簡單方式。
重要
大部分 DBMS 使用比較些方式更複雜的結構描述以增加並行。 這些範例僅提供作為說明之用。 特別是 ODBE 不會指定特定 DBMS 如何相互隔離交易。
交易隔離 | 可能的實作 |
---|---|
讀取未認可 | 交易不會相互隔離。 如果 DBMS 支援其他交易隔離等級,則會忽略用於實作這些等級的機制。 因此,不會對其他交易造成負面影響,讀取未認可層及執行的交易通常為唯讀。 |
讀取認可 | 交易會等到其他交易鎖定的資料列寫入解除鎖定為止,這可防止讀取其他「中途」資料。 交易會保留目前資料列上的讀取鎖定 (若僅讀取資料列) 或寫入鎖定 (若更新或刪除資料列),防止其他交易進行更新或刪除。 當交易移離目前資料列時,該交易會釋放讀取鎖定。 同時保留寫入鎖定,直到認可或復原為止。 |
可重複讀取 | 交易會等到其他交易鎖定的資料列寫入解除鎖定為止,這可防止讀取其他「中途」資料。 交易會保留其傳回至應用程式的所有資料列上讀取鎖定和其插入、更新或刪除的所有資料列上寫入鎖定。 例如,如果交易包含 SQL 陳述式 SELECT * FROM Orders,則在應用程式擷取時,交易會讀取鎖定資料列。 如果交易包含 SQL 陳述式 DELETE FROM Orders WHERE Status = 'CLOSED',則在刪除時,交易會寫入鎖定資料列。 由於其他資料列無法更新或刪除這些資料列,因此目前交易會避免任何不可重複讀取。 在認可或復原時,交易會釋放其鎖定。 |
可序列化 | 交易會等到其他交易鎖定的資料列寫入解除鎖定為止,這可防止讀取其他「中途」資料。 交易會保留其影響資料列範圍上的讀取鎖定 (若僅讀取資料列) 或寫入鎖定 (若可更新或刪除資料列)。 例如,如果交易包含 SQL 陳述式 SELECT * FROM Orders,則範圍為整個 Orders 表格;交易會讀取鎖定表格並不允許插入至其中的任何新資料列。 如果交易包含 SQL 陳述式 DELETE FROM Orders WHERE Status = 'CLOSED',則範圍為狀態為 "CLOSED" 的所有資料列;交易會寫入鎖定在 Orders 表格中狀態為 "CLOSED" 的所有資料列,且不允許插入或更新而導致資料列狀態為 "CLOSED" 的任何資料列。 由於其他資料列無法更新或刪除範圍中的資料列,因此目前交易會避免任何不可重複讀取。 由於其他交易無法插入範圍中的資料列,因此目前交易會避免任何虛設項目。 在認可或復原時,交易會釋放其鎖定。 |
請務必注意,交易隔離等級不會影響查看其本身變更的交易功能;交易一律可察看所做的任何變更。 例如,交易可能包含兩個 UPDATE 陳述式,其中一個會將所有員工的薪水提高 10%,而第二個會將超過上限金額的員工薪水設定為該金額。 由第二個 UPDATE 陳述式可看到第一個結果,因此會以單一交易成功進行。