Locking
使用事務寫入表而不鎖定
是否可以使用事務寫入數據庫表而不鎖定它?
我想對單個記錄中的單個欄位執行更新查詢,但以防萬一我的應用程序出現錯誤,我希望能夠將其回滾。該應用程序可能需要一兩秒鐘才能完成整個過程,所以我想防止它鎖定表,因為它是一個讀取量很大的表。從應用程序的角度來看,該欄位是微不足道的,所以我不在乎它是否有臟讀。
(我知道 SELECT 語句的 NOLOCK 和 READPAST ,但我不是在尋找解決方案。)
任何幫助表示讚賞。
是否可以使用事務寫入數據庫表而不鎖定它?
取決於你所說的“它”是什麼意思?鎖可以在不同的資源級別含義:行、頁、表、非聚集索引頁等。
如果您的意思是以上所有內容,那麼答案是否定的。同時,您可以避免鎖定某些資源,具體取決於您的事務範圍和要更新的記錄數。
我建議你閱讀這篇文章:
為什麼我們需要 SQL Server 中的 UPDATE 鎖?克勞斯·阿申布倫納
現在讓我們看一個使用 Adventureworks 數據庫的範例。為了模擬我在做什麼,你可以從這裡下載這個數據庫。
USE [AdventureWorks] GO --Making sure we are only updating one row SELECT COUNT(0) FROM [Production].[Product] WHERE ProductId=318 BEGIN TRAN UPDATE [Production].[Product] SET [Name]='ML Crankarm_modified' WHERE ProductId=318 --ROLLBACK TRAN
由於我們正在使用
BEGIN TRAN
(顯式事務),我們可以檢查此會話持有什麼鎖。SELECT resource_type, resource_database_id, resource_associated_entity_id, request_mode, request_status, request_session_id FROM sys.dm_tran_locks WHERE request_session_id=59
查看這些鎖和鎖兼容性圖表,您應該能夠弄清楚您可以執行哪些選擇語句以及哪些語句會被阻塞。請記住,它也將由您的事務隔離級別決定。
例如,您在 object id 482100758 上具有 Intent Exclusive 鎖,這是 production.product 表本身,並且此鎖與共享鎖不兼容。因此,您不能從該表中選擇所有記錄。但是,如果您想選擇一個或多個沒有與共享鎖不兼容的鎖的記錄,您應該能夠選擇數據。