在 SQL Server 環境中,鎖定機制是確保資料完整性與一致性的核心基石。然而,不當的鎖定往往會導致阻塞、死鎖,嚴重拖垮系統效能。本文將針對報表查詢與線上交易處理(OLTP)兩大典型場景,提供避免不必要鎖定的實務解決方案。
報表系統通常對資料即時性要求較低,但查詢量大、掃描範圍廣,極易與核心業務搶奪鎖資源。可從以下三個層面優化:
利用交易式複寫、Log Shipping 或第三方同步工具,將生產庫資料同步至專屬報表伺服器。雖然資料會有秒級至分鐘級延遲,但徹底消除了報表查詢對線上業務的鎖衝突,是企業級架構的首選方案。
對於固定週期(如每分鐘、每 5 分鐘)的標準化報表,建議建立物化視圖或摘要表,由排程任務定期刷新。查詢時直接讀取預計算結果,鎖定僅發生在極短的刷新窗口期,大幅降低基礎表壓力。
當上述方案均不可行,且業務可容忍「髒讀」時,可在報表應用程式的資料庫連接建立階段,執行:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
此舉讓該會話下的所有 SELECT 不再申請共享鎖(S Lock),亦不會被獨佔鎖(X Lock)阻塞。需注意:此設定僅影響當前會話,不改變資料庫預設行為。
核心交易系統絕不可犧牲 ACID 特性。若特定查詢(如即時儀表板、非關鍵輔助查詢)確需避免鎖定,應採用語句級 Hint:
SELECT columns FROM table WITH (NOLOCK) WHERE ...;
NOLOCK 等同於 READ UNCOMMITTED,但作用範圍僅限該語句,不影響事務內其他操作的隔離等級。務必確認業務邏輯能接受髒讀、不可重複讀等異常現象後再使用。
READ COMMITTED 隔離等級是經過嚴格驗證的平衡點,全域修改風險極高。NOLOCK。sys.dm_tran_locks、sys.dm_os_wait_stats 量化鎖等待變化,以數據說話。鎖定不是敵人,失控的鎖定才是。掌握場景化策略,才能在一致性與效能間找到最佳平衡點。