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

SQL Server 事務隔離等級完整指南:五大模式原理、問題與選擇策略

     編輯:關於SqlServer

SQL Server 提供五種事務隔離等級,平衡資料一致性與並發效能。本文系統整理三大並發異常(髒讀、不可重複讀、幻影讀)、五大隔離等級解決範圍、設定語法與選擇決策指南。

三大並發異常定義

異常發生情境後果
髒讀交易 A 讀取交易 B 修改但未提交的資料若 B 回滾,A 讀到的資料無效(髒資料)
不可重複讀交易 A 兩次讀取同一資料,中間交易 B 修改並提交A 兩次讀到不同值,邏輯判斷失效
幻影讀交易 A 多次查詢同一範圍,中間交易 B 插入/刪除符合條件的列A 發現列數變化,如見鬼魅

五大隔離等級對照表

隔離等級髒讀不可重複讀幻影讀機制並發度
READ UNCOMMITTED❌ 允許❌ 允許❌ 允許無共享鎖,等同 NOLOCK最高
READ COMMITTED (預設)✅ 防止❌ 允許❌ 允許讀取已提交資料,釋放共享鎖高
REPEATABLE READ✅ 防止✅ 防止❌ 允許持有共享鎖至交易結束中
SERIALIZABLE✅ 防止✅ 防止✅ 防止範圍鎖,完全序列化低
SNAPSHOT✅ 防止✅ 防止✅ 防止MVCC 版本鏈,讀不阻寫高(資源換並發)

各等級深度行為解析

1. READ UNCOMMITTED(髒讀)

-- 會話 A
BEGIN TRAN
INSERT INTO Customer VALUES ('123','123')
WAITFOR DELAY '00:00:20'
COMMIT TRAN

-- 會話 B
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM Customer  -- 立即看到 '123',若 A 回滾即為髒讀

相當於 WITH (NOLOCK)。適合:報表查詢可容忍髒資料、資料倉庫 ETL 階段掃描。

2. READ COMMITTED(提交讀,預設)

只見已提交資料。無法防止:同一交易中兩次查詢結果不同(不可重複讀)、範圍查詢列數變化(幻影讀)。

3. REPEATABLE READ(可重複讀)

-- 會話 A
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
SELECT * FROM Customer WHERE ID = 17
WAITFOR DELAY '00:00:30'
SELECT * FROM Customer WHERE ID = 17  -- 兩次結果保證相同
COMMIT TRAN

-- 會話 B (在 30 秒內)
UPDATE Customer SET Title = 'd' WHERE ID = 17  -- 被阻塞等待 A 結束

持有共享鎖至交易結束,阻塞修改。無法防止幻影讀(新增列不受共享鎖保護)。

4. SERIALIZABLE(序列化)

-- 會話 A
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
UPDATE Customer SET Title = '111'
WAITFOR DELAY '00:00:20'
COMMIT TRAN

-- 會話 B (在 20 秒內)
INSERT INTO Customer VALUES ('2','2')  -- 被範圍鎖阻塞,避免幻影讀

最嚴格等級,並發度最低,易發生死鎖與逾時。僅用於極高一致性需求(如財務結帳)。

5. SNAPSHOT(快照隔離)

啟用資料庫選項:ALTER DATABASE SET ALLOW_SNAPSHOT_ISOLATION ON。
讀取資料快照(版本鏈),讀不阻寫、寫不阻讀。寫入衝突時以錯誤 3960 終止其中一交易(樂觀並發)。

設定語法

SET TRANSACTION ISOLATION LEVEL 
    READ COMMITTED 
  | READ UNCOMMITTED 
  | REPEATABLE READ 
  | SERIALIZABLE 
  | SNAPSHOT;

選擇決策指南

業務場景推薦等級理由
高並發 OLTP 核心交易(訂單、扣款)READ COMMITTED / SNAPSHOT平衡一致性與並發,SNAPSHOT 避免鎖爭用
報表/分析查詢,可容忍髒資料READ UNCOMMITTED (NOLOCK)最高並發,無鎖負擔
需在同一交易多次讀取同一資料且必須一致REPEATABLE READ防止不可重複讀,較 SERIALIZABLE 輕量
財務結帳、庫存盤點等嚴格一致性SERIALIZABLE完全隔離,接受低並發
長交易讀取、高爭用熱點資料SNAPSHOT消除讀寫阻塞,需評估版本存放區成本

重要提醒

  • 隔離等級設定為Session 級別,不影響其他連線。
  • NOLOCK / READ UNCOMMITTED 可能讀到「半寫入」資料頁(中斷的更新),極少見但理論存在。
  • SNAPSHOT 需額外儲存空間與 CPU 維護版本鏈,TempDB 壓力會增加。
  • 實際部署前務必進行負載測試,觀察鎖等待、死鎖、版本存放區大小指標。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved