多用戶並發操作導致三大資料不一致問題:
鎖即在一段時間內禁止特定操作,實現悲觀並發控制。
| 模式 | 縮寫 | 用途 | 相容性 |
|---|---|---|---|
| 共享鎖 | S | 唯讀操作 (SELECT) | 與 S、U 相容;與 X 不相容 |
| 更新鎖 | U | 讀取後可能更新,防止死鎖 | 與 S 相容;與 U、X 不相容 |
| 排他鎖 | X | 資料修改 (INSERT/UPDATE/DELETE) | 與所有鎖不相容 |
| 意向鎖 | IS/IX/SIX | 建立鎖層級,表示下層將加 S/X 鎖 | 提升效能,僅檢查表層 |
| 結構描述鎖 | Sch-M/Sch-S | DDL 操作 / 編譯查詢計畫 | Sch-M 獨佔;Sch-S 共享 |
| 大量更新鎖 | BU | 大量複製 + TABLOCK | 特定場景 |
| 資源 | 描述 |
|---|---|
| RID | 列識別碼,Heap 表單列鎖 |
| Key | 索引鍵,保護可序列化交易的鍵範圍 |
| Page | 8KB 資料/索引頁 |
| Extent | 8 頁組成的擴展區 |
| Table | 整個表 (含索引) |
| Database | 整個資料庫 |
粒度越細並發度越高但開銷越大,SQL Server 動態升級 (Row → Page → Table)。
READ COMMITTED 僅讀取頁期間;HOLDLOCK/REPEATABLE READ/SERIALIZABLE 持有至交易結束HOLDLOCK 則至交易結束SET LOCK_TIMEOUT)| 機制 | 語法/工具 | 用途 |
|---|---|---|
| 死鎖優先級 | SET DEADLOCK_PRIORITY LOW/NORMAL/HIGH/@var | 犧牲低優先級進程 |
| 鎖逾時 | SET LOCK_TIMEOUT 1800 (毫秒),@@LOCK_TIMEOUT 查詢 | 避免無限等待,逾時返回錯誤 1222 |
| 交易隔離級別 | SET TRANSACTION ISOLATION LEVEL ... | 控制共享鎖行為 |
| 表層鎖定提示 | WITH (NOLOCK, HOLDLOCK, UPDLOCK, TABLOCK...) | 單一陳述式覆蓋預設行為 |
| 索引鎖粒度 | sp_indexoption 'table.index', 'DisAllowPageLocks', 'true' | 禁止頁鎖強制列鎖 |
EXEC sp_lock 報告目前鎖狀態sys.dm_tran_locks, sys.dm_os_waiting_tasksLOCK_TIMEOUT (3~10 分鐘),避免進程永久掛起@@ERROR/TRY...CATCH 錯誤處理-- 鎖定單列
SELECT * FROM table WITH (ROWLOCK, UPDLOCK) WHERE id = 1;
-- 鎖定整表 (持有至交易結束)
SELECT * FROM table WITH (TABLOCK, HOLDLOCK);
-- Sybase 風格 (舊版相容)
UPDATE table SET col1 = col1 WHERE ... -- 產生排他鎖