語法
SET TRANSACTION ISOLATION LEVEL ????{ READ UNCOMMITTED ????| READ COMMITTED ????| REPEATABLE READ ????| SNAPSHOT ????| SERIALIZABLE ????} [ ; ] |
備注
一次只能設置一個隔離級別選項,而且設置的選項將一直對那個連接始終有效,直到顯式更改該選項為止。事務中執(zhí)行的所有讀取操作都會在指定的隔離級別的規(guī)則下運行,除非語句的 FROM 子句中的表提示為表指定了其他鎖定行為或版本控制行為。
事務隔離級別定義了可為讀取操作獲取的鎖類型。針對 READ COMMITTED 或 REPEATABLE READ 獲取的共享鎖通常為行鎖,盡管當讀取引用了頁或表中大量的行時,行鎖可以升級為頁鎖或表鎖。如果某行在被讀取之后由事務進行了修改,則該事務會獲取一個用于保護該行的排他鎖,并且該排他鎖在事務完成之前將一直保持。例如,如果 REPEATABLE READ 事務具有用于某行的共享鎖,并且該事務隨后修改了該行,則共享行鎖便會轉換為排他行鎖。
當事務進行時,您可以隨時將事務從一個隔離級別更改為另一個隔離級別。將事務從一個隔離級別更改為另一個隔離級別之后,便會根據(jù)新級別的規(guī)則對更改后讀取的資源執(zhí)行保護。更改前讀取的資源將繼續(xù)根據(jù)先前級別的規(guī)則進行保護,例如,一個事務由 REPEATABLE READ 更改為 SERIALIZABLE。由更改前發(fā)出的 SELECT 語句讀取的行將繼續(xù)受到行級、頁級或表級共享鎖的保護。這些鎖會繼續(xù)保持,直至事務結束。由 SELECT 語句在更改后讀取的行將受到范圍鎖的保護。
該表顯示事務從一個隔離級別更改為另一個隔離級別時的鎖定行為。
?
更改前的隔離級別 更改后的隔離級別
READ UNCOMMITTED |
READ UNCOMITTED: 未更改。 READ COMMITTED: 該行為取決于 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項的設置: 如果為 OFF,事務將獲取共享鎖,并在讀取期間保留鎖。 如果為 ON,事務會使用行版本控制。 SNAPSHOT: 事務必須已作為 SNAPSHOT 啟動。事務將會失敗,并將回滾所有更改。 REPEATABLE READ: 現(xiàn)在該事務將獲取共享鎖,并在事務期間保留鎖。 SERIALIZABLE: 現(xiàn)在該事務將獲取范圍鎖,并在事務期間保留鎖。 |
READ COMMITTED |
READ UNCOMITTED: 事務不再獲取用于讀取操作的鎖。 READ COMMITTED: 未更改。 SNAPSHOT: 事務必須已作為 SNAPSHOT 啟動。事務將會失敗,并將回滾所有更改。 REPEATABLE READ: 現(xiàn)在該事務將獲取共享鎖,并在事務期間保留鎖。 SERIALIZABLE: 現(xiàn)在該事務將獲取范圍鎖,并在事務期間保留鎖。 |
SNAPSHOT |
READ UNCOMITTED: 事務不再使用行版本控制,并且不再獲取用于讀取操作的鎖。 READ COMMITTED: 該行為取決于 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項的設置: 如果為 OFF,事務將獲取共享鎖,并在讀取期間保留鎖。 如果為 ON,事務會使用行版本控制。 SNAPSHOT: 未更改。 REPEATABLE READ: 該事務不再使用行版本控制。現(xiàn)在它獲取了共享鎖,并在事務執(zhí)行期間一直保持該鎖。 SERIALIZABLE: 該事務不再使用行版本控制。現(xiàn)在它獲取了范圍鎖,并在事務執(zhí)行期間一直保持該鎖。 |
REPEATABLE READ |
READ UNCOMITTED: 該事務在讀取操作時不再獲取鎖。在 REPEATABLE READ 下獲取的共享鎖保留到事務結束。 READ COMMITTED: 該行為取決于 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項的設置: 如果為 OFF,事務將獲取共享鎖,并在讀取期間保留這些新鎖。 如果為 ON,事務會使用行版本控制。 在 REPEATABLE READ 下獲取的共享鎖保留到事務結束。 SNAPSHOT: 事務必須已作為 SNAPSHOT 啟動。事務將會失敗,并將回滾所有更改。 REPEATABLE READ: 未更改。 SERIALIZABLE: 現(xiàn)在該事務將獲取范圍鎖,并在事務期間保留鎖。在 REPEATABLE READ 下獲取的共享鎖保留到事務結束。 |
SERIALIZABLE |
READ UNCOMITTED: 該事務在讀取操作時不再獲取鎖。在 SERIALIZABLE 下獲取的范圍鎖保留到事務結束。 READ COMMITTED: 該行為取決于 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項的設置: 如果為 OFF,事務將獲取共享鎖,并在讀取期間保留這些新鎖。 如果為 ON,事務會使用行版本控制。 在 SERIALIZABLE 級別下獲取了范圍鎖,并且該鎖一直保持到事務結束。 SNAPSHOT: 事務必須已作為 SNAPSHOT 啟動。事務將會失敗,并將回滾所有更改。 REPEATABLE READ: 現(xiàn)在,事務獲取了共享鎖,并在事務執(zhí)行期間一直保持該鎖。在 SERIALIZABLE 下獲取的范圍鎖保留到事務結束。 SERIALIZABLE: 未更改。 |
如果在存儲過程、觸發(fā)器、用戶定義函數(shù)或用戶定義類型中發(fā)出 SET TRANSACTION ISOLATION LEVEL,則當對象返回控制時,隔離級別會重設為在調用對象時有效的級別。例如,如果在批處理中設置 REPEATABLE READ,并且該批處理調用一個將隔離級別設置為 SERIALIZABLE 的存儲過程,則當該存儲過程將控制返回給該批處理時,隔離級別就會恢復為 REPEATABLE READ。
當您使用 sp_bindsession 綁定兩個會話時,每個會話都會保留它自身的隔離級別設置。使用 SET TRANSACTION ISOLATION LEVEL 更改某個會話的隔離級別設置時,不會影響與該會話綁定的其他任何會話的設置。
SET TRANSACTION ISOLATION LEVEL 會在執(zhí)行或運行時生效,而不是在分析時生效。
對表執(zhí)行的優(yōu)化大容量導入操作會阻塞在下列隔離級別下運行的查詢:
SNAPSHOT
READ UNCOMMITTED
使用行版本控制的 READ COMMITTED
反之,在這些隔離級別下運行的查詢也會阻塞優(yōu)化大容量導入操作。
參數(shù)
指定語句可以讀取已由其他事務修改但尚未提交的行。
在 READ UNCOMMITTED 級別運行的事務,不會發(fā)出共享鎖來防止其他事務修改當前事務讀取的數(shù)據(jù)。READ UNCOMMITTED 事務也不會被排他鎖阻塞,排他鎖會禁止當前事務讀取其他事務已修改但尚未提交的行。設置此選項之后,可以讀取未提交的修改,這種讀取稱為臟讀。在事務結束之前,可以更改數(shù)據(jù)中的值,行也可以出現(xiàn)在數(shù)據(jù)集中或從數(shù)據(jù)集中消失。該選項的作用與在事務內所有 SELECT 語句中的所有表上設置 NOLOCK 相同。這是隔離級別中限制最少的級別。
在 SQL Server 2005 中,您還可以使用下列任意一種方法,在保護事務不臟讀未提交的數(shù)據(jù)修改的同時盡量減少鎖定爭用:
READ COMMITTED 隔離級別,并將 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項設置為 ON。
SNAPSHOT 隔離級別。
指定語句不能讀取已由其他事務修改但尚未提交的數(shù)據(jù)。這樣可以避免臟讀。其他事務可以在當前事務的各個語句之間更改數(shù)據(jù),從而產(chǎn)生不可重復讀取和幻像數(shù)據(jù)。該選項是 SQL Server 的默認設置。
READ COMMITTED 的行為取決于 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項的設置:
如果將 READ_COMMITTED_SNAPSHOT 設置為 OFF(默認設置),則數(shù)據(jù)庫引擎?會使用共享鎖防止其他事務在當前事務執(zhí)行讀取操作期間修改行。共享鎖還會阻止語句在其他事務完成之前讀取由這些事務修改的行。語句完成后便會釋放共享鎖。
如果將 READ_COMMITTED_SNAPSHOT 設置為 ON,則數(shù)據(jù)庫引擎?會使用行版本控制為每個語句提供一個在事務上一致的數(shù)據(jù)快照,因為該數(shù)據(jù)在語句開始時就存在。不使用鎖來防止其他事務更新數(shù)據(jù)。
當 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項設置為 ON 時,您可以使用 READCOMMITTEDLOCK 表提示為 READ_COMMITTED 隔離級別上運行的事務中的各語句請求共享鎖,而不是行版本控制。
指定語句不能讀取已由其他事務修改但尚未提交的行,并且指定,其他任何事務都不能在當前事務完成之前修改由當前事務讀取的數(shù)據(jù)。
對事務中的每個語句所讀取的全部數(shù)據(jù)都設置了共享鎖,并且該共享鎖一直保持到事務完成為止。這樣可以防止其他事務修改當前事務讀取的任何行。其他事務可以插入與當前事務所發(fā)出語句的搜索條件相匹配的新行。如果當前事務隨后重試執(zhí)行該語句,它會檢索新行,從而產(chǎn)生幻讀。由于共享鎖一直保持到事務結束,而不是在每個語句結束時釋放,所以并發(fā)級別低于默認的 READ COMMITTED 隔離級別。此選項只在必要時使用。
指定事務中任何語句讀取的數(shù)據(jù)都將是在事務開始時便存在的數(shù)據(jù)的事務上一致的版本。事務只能識別在其開始之前提交的數(shù)據(jù)修改。在當前事務中執(zhí)行的語句將看不到在當前事務開始以后由其他事務所做的數(shù)據(jù)修改。其效果就好像事務中的語句獲得了已提交數(shù)據(jù)的快照,因為該數(shù)據(jù)在事務開始時就存在。
除非正在恢復數(shù)據(jù)庫,否則 SNAPSHOT 事務不會在讀取數(shù)據(jù)時請求鎖。讀取數(shù)據(jù)的 SNAPSHOT 事務不會阻止其他事務寫入數(shù)據(jù)。寫入數(shù)據(jù)的事務也不會阻止 SNAPSHOT 事務讀取數(shù)據(jù)。
在數(shù)據(jù)庫恢復的回滾階段,如果嘗試讀取由其他正在回滾的事務鎖定的數(shù)據(jù),則 SNAPSHOT 事務將請求一個鎖。在事務完成回滾之前,SNAPSHOT 事務會一直被阻塞。當事務取得授權之后,便會立即釋放鎖。
必須將 ALLOW_SNAPSHOT_ISOLATION 數(shù)據(jù)庫選項設置為 ON,才能開始一個使用 SNAPSHOT 隔離級別的事務。如果使用 SNAPSHOT 隔離級別的事務訪問多個數(shù)據(jù)庫中的數(shù)據(jù),則必須在每個數(shù)據(jù)庫中將 ALLOW_SNAPSHOT_ISOLATION 都設置為 ON。
不能將通過其他隔離級別開始的事務設置為 SNAPSHOT 隔離級別,否則將導致事務中止。如果一個事務在 SNAPSHOT 隔離級別開始,則可以將它更改為另一個隔離級別,然后再返回 SNAPSHOT。一個事務從執(zhí)行 BEGIN TRANSACTION 語句開始。
在 SNAPSHOT 隔離級別下運行的事務可以查看由該事務所做的更改。例如,如果事務對表執(zhí)行 UPDATE,然后對同一個表發(fā)出 SELECT 語句,則修改后的數(shù)據(jù)將包含在結果集中。
指定:
語句不能讀取已由其他事務修改但尚未提交的數(shù)據(jù)。
任何其他事務都不能在當前事務完成之前修改由當前事務讀取的數(shù)據(jù)。
在當前事務完成之前,其他事務不能使用當前事務中任何語句讀取的鍵值插入新行。
范圍鎖處于與事務中執(zhí)行的每個語句的搜索條件相匹配的鍵值范圍之內。這樣可以阻止其他事務更新或插入任何行,從而限定當前事務所執(zhí)行的任何語句。這意味著如果再次執(zhí)行事務中的任何語句,則這些語句便會讀取同一組行。在事務完成之前將一直保持范圍鎖。這是限制最多的隔離級別,因為它鎖定了鍵的整個范圍,并在事務完成之前一直保持范圍鎖。因為并發(fā)級別較低,所以應只在必要時才使用該選項。該選項的作用與在事務內所有 SELECT 語句中的所有表上設置 HOLDLOCK 相同。
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
