首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 交易 (Transaction) 核心觀念:ACID 特性、隔離等級、鎖定機制與管理語法全解析

     編輯:關於SqlServer

交易是資料庫一致性的基石。本文系統闡述交易的定義、ACID 四大特性、四種隔離等級 (Read Uncommitted 到 Serializable)、鎖定與封鎖關係、死鎖成因、常用 T-SQL 管理語法 (BEGIN/COMMIT/ROLLBACK/SAVE TRANSACTION) 與巢狀交易行為,並附上隔離等級選擇決策表,助你設計正確且高併發的資料庫操作邏輯。

什麼是交易?

  • 單一邏輯工作單元,包含一或多條 T-SQL 陳述式 (SELECT/INSERT/UPDATE/DELETE)。
  • 隱式交易:每條陳述式自動視為一個交易 (自動提交模式)。
  • 顯式交易:以 BEGIN TRANSACTION 開啟,COMMIT 或 ROLLBACK 結束。
  • 所有操作寫入交易記錄檔,透過 檢查點 機制定期將認可頁面刷新至資料檔,保證耐久性與可復原。

ACID 四大特性

特性英文核心定義實現機制
原子性Atomicity全做或全不做,無中間狀態記錄檔 + 復原管理員 (Undo/Redo)
一致性Consistency交易前後資料庫滿足所有完整性約束 (PK, FK, CHECK, Trigger)約束驗證 + 觸發器 + 應用層邏輯
隔離性Isolation並發交易互不干擾,看不到彼此未認可的中間狀態鎖定 (Lock) + 版本存儲 (Row Versioning)
耐久性Durability認可後永久生效,不因系統故障遺失Write-Ahead Logging (WAL) + 檢查點

交易管理核心語法

-- 開啟交易
BEGIN TRANSACTION [tran_name | @tran_name_var] [WITH MARK ['description']];

-- 認可交易 (寫入記錄檔認可標記,釋放鎖)
COMMIT TRANSACTION [tran_name | @tran_name_var];

-- 回滾交易 (撤銷所有操作,釋放鎖)
ROLLBACK TRANSACTION [tran_name | @tran_name_var | savepoint_name];

-- 設定儲存點 (支援部分回滾)
SAVE TRANSACTION savepoint_name;

-- 範例:巢狀交易與儲存點
BEGIN TRAN T1;
    INSERT INTO T1 VALUES (1);
    SAVE TRANSACTION SP1;
    BEGIN TRAN T2;  -- 實際上只是計數器 +1,不建立新交易
        INSERT INTO T2 VALUES (2);
        ROLLBACK TRANSACTION SP1;  -- 僅回滾到 SP1,T1 的 INSERT 保留
    COMMIT TRANSACTION T2;
COMMIT TRANSACTION T1;

關鍵規則:
• @@TRANCOUNT 遞增/遞減追蹤巢狀層級,只有最外層 COMMIT 真正寫入認可。
• ROLLBACK 無參數時回滾至最外層 BEGIN,@@TRANCOUNT 歸零。
• SAVE TRANSACTION 僅標記點,不影響 @@TRANCOUNT。

四種隔離等級 (由低到高)

等級別名髒讀不可重複讀虛讀鎖定策略適用場景
Read Uncommitted未授權讀取✅ 允許✅ 允許✅ 允許排他寫鎖 (Sch-S)報表/查詢容忍髒資料、極高併發
Read Committed授權讀取 (預設)❌ 禁止✅ 允許✅ 允許瞬間共享讀鎖 + 排他寫鎖一般 OLTP,平衡一致性與併發
Repeatable Read可重複讀取❌ 禁止❌ 禁止✅ 允許共享讀鎖持有至交易結束 + 排他寫鎖需穩定讀取集合的報表/批次
Serializable可序列化❌ 禁止❌ 禁止❌ 禁止範圍鎖 (Key-Range) 防止 Phantom極高一致性需求 (金融結算)、低併發

補充:Snapshot 隔離 (Row Versioning based)

  • Read Committed Snapshot (RCSI):資料庫層級開啟,Read Committed 行為改為讀取版本存儲,讀不阻寫、寫不阻讀,無髒讀。
  • Snapshot Isolation:交易層級指定,整個交易看到陳述式開始時的資料快照,支援樂觀併發,衝突時回滾。
  • 啟用:ALTER DATABASE db SET READ_COMMITTED_SNAPSHOT ON / ALLOW_SNAPSHOT_ISOLATION ON (需單用戶模式)。

死鎖成因與預防

成因:交易 A 鎖資源 1 等資源 2,交易 B 鎖資源 2 等資源 1,形成循環等待。

預防原則:

  1. 統一存取順序:所有交易按相同順序鎖定資源 (如先表 A 再表 B)。
  2. 避免交易中等待使用者輸入:長時間持有鎖導致封鎖鏈。
  3. 縮短交易範圍與持續時間:單一批次完成,減少網路往返。
  4. 降低隔離等級:RCSI 或 READ UNCOMMITTED (NOLOCK) 減少共享鎖持有。
  5. 使用繫結連接:同一應用多連線共享鎖空間。
  6. 索引優化:減少掃描範圍 → 縮小鎖定粒度與時間。

隔離等級選擇決策表

業務需求建議等級設定方式
高併發查詢、容忍臨時不一致READ UNCOMMITTED / NOLOCKSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 或 WITH(NOLOCK)
標準 OLTP、預設行為READ COMMITTED無需設定 (預設) 或開啟 RCSI
報表/批次需穩定讀取集合REPEATABLE READSET TRANSACTION ISOLATION LEVEL REPEATABLE READ
金融結算/庫存扣款、零容忍 PhantomSERIALIZABLESET TRANSACTION ISOLATION LEVEL SERIALIZABLE
高併發寫入、需樂觀併發SNAPSHOT資料庫啟用 ALLOW_SNAPSHOT_ISOLATION + SET TRANSACTION ISOLATION LEVEL SNAPSHOT

深入理解交易與隔離機制,能讓你在一致性與併發性的天平上做出精準權衡,寫出既正確又高效的資料庫程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved