在Oracle當中,Select…For Update會給予所查詢的資料鎖定(RX),當其他的Session執行相同的陳述式時,必須等待上一個Session交易結束之後,才會繼續執行。如果在SQL Server當中我們也希望能達到這樣的效果,我們應該怎麼做 ?
ORACLE:
Select…For Update語法,是用來鎖定特定的row,並給予這些row等級3的Row-X (RX)。
當這些row被鎖定後,其他session可以選擇這些row,但不能更改或刪除這些row,直到該語句的session被commit或rollback為止。
SQL SERVER:
共用鎖定(Shared Lock) (S)
當我們要查詢(SELECT)某筆記錄時,SQL Server 會嘗試先取得該記錄的共用鎖定(S),若無法取得,就必須等到別人釋放對該記錄某幾種與共用鎖定互斥的鎖定後,才可以在設定完共用鎖定後,取得該筆記錄。
獨占鎖定(Exclusive Lock) (X)
當要新增、修改、刪除每個資源時,需要先對該資源下獨占鎖定,保證資料更新的動作尚未完成時,不會被干擾。獨占鎖定會在開啟交易後,一直保留到交易結束為止。
更新鎖定(Update Lock) (U)
更新鎖定是一種中繼的鎖定。
當資源更新時所使用的模式。某一時刻對某一資源只能有一個交易可以獲得更新鎖定。如果交易確實作了修改,更新鎖定就轉為獨占鎖定;否則,轉為共用鎖定。
意圖鎖定(Intent Lock) (IS, IU, IX)
當該記錄要放上共用鎖定前,需要對存放該記錄的更大範圍設定 Intent Shared 鎖定,例如要對包含該記錄的分頁(Page)、資料表放上 Intent Shared 鎖定。以避免別的連線嘗試對該分頁下獨占鎖定。
舉例來說,當某個人在查詢某些資源時,會在該資源放上共用鎖定,而其他人若同時也要查詢這些資源,因為共用鎖定彼此不互斥,所以也可以再設定共用鎖定,也就是可以同時讀取。
但若有人在此時要嘗試更新資料,則會因為獨占鎖定與共用鎖定互斥,因此無法設定獨占鎖定,要等到所有讀取該資料的人都讀取完畢,釋放共用鎖定,則嘗試要更新的人才得以對該資源設定獨占鎖定,而後更新資料。
我們可以在撰寫T-SQL 語法時,加入鎖定提示(Lock Hint),控制所查詢的資源。
XLOCK:使用獨占鎖定並持有直到執行於陳述式所處理之所有資料的交易結束為止。
ROWLOCK:強制採用資料列層級鎖定,不允許自動升級成範圍較大的分頁與資料表層級鎖定。
TABLOCK:對資料表使用獨占鎖定,直到陳述式或交易結束為止。
READPAST:略過其他交易所鎖定的資料列。只能用於在「讀取認可」隔離等級中執行的交易。