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

SQL Server vs Oracle 並行控制機制深度對比:鎖 vs MVCC

     編輯:關於SqlServer

資料庫並行控制是決定高併發下效能與一致性的核心。SQL Server (鎖基礎 + 行版本存放於 TempDB) 與 Oracle (純 MVCC,Undo Tablespace 存前映像) 代表兩大主流架構流派。本文深度剖析兩者在讀寫衝突、一致性語義、鎖升級、版本存儲管理、應用層影響等維度的本質差異。

核心架構對比

維度SQL Server (預設 READ COMMITTED)Oracle (READ COMMITTED / SERIALIZABLE)
核心機制鎖 + 可選行版本 (RCSI/SI)多版本並行控制 (MVCC)
讀取者是否阻塞寫入者預設 是 (共享鎖 S 阻塞排他鎖 X)否 (讀取 Undo 中的前映像)
寫入者是否阻塞讀取者預設 是 (X 鎖阻塞 S 鎖)否 (讀取提交前的舊版本)
讀取一致性層級語句級 (預設) / 交易級 (SNAPSHOT/Serializable)語句級 (RC) / 交易級 (Serializable)
版本存儲位置TempDB (版本存放區)Undo Tablespace / Rollback Segments
版本清理機制Ghost Cleanup / Version Store 清理執行緒Undo 保留時間 (UNDO_RETENTION) 自動覆寫

實戰場景演示:修改資料時的並發查詢

SQL Server 行為 (預設隔離級別)

-- 會話 1:開始修改,未提交
BEGIN TRAN;
UPDATE titles SET price = price * 1.05 WHERE title_id = 'BU2075';
-- 未 COMMIT/ROLLBACK

-- 會話 2:查詢同一資料表
SELECT title_id, title, price FROM titles ORDER BY title_id;
-- 結果:卡住等待,直到會話 1 提交或回滾

原因:會話 1 持有 X 鎖,會話 2 請求 S 鎖,相互阻塞。

繞過方案:SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 或 WITH (NOLOCK),但會讀到「髒資料」(未提交資料),不保證一致性。

Oracle 行為 (預設 READ COMMITTED)

-- 會話 1:修改薪資,未提交
UPDATE hr.employees SET salary = salary * 1.05 WHERE department_id = 20;

-- 會話 2:查詢同一資料
SELECT first_name, last_name, salary FROM hr.employees WHERE department_id = 20;
-- 結果:立即返回修改前的薪資 (一致性快照)
-- 會話 1 COMMIT 後,會話 2 重新查詢才會看到新薪資

原因:Oracle 將修改前的資料版本寫入 Undo Tablespace,查詢自動讀取舊版本,不需等待鎖釋放。

深度剖析:版本存儲與風險

SQL Server:TempDB 版本存放區

  • 啟用 READ_COMMITTED_SNAPSHOT ON (RCSI) 或 ALLOW_SNAPSHOT_ISOLATION ON (SI) 後,寫入者在 TempDB 維護資料列版本。
  • 長時間執行的查詢可能因版本存放區壓力 (TempDB 滿) 失敗,錯誤 3967。
  • 優點:TempDB 由引擎自動管理,DBA 維護負擔低。

Oracle:Undo Tablespace / Rollback Segments

  • Oracle 8i 及之前:手動管理 Rollback Segments (數量、大小、最佳化),配置不當導致「Snapshot too old」 (ORA-01555)。
  • Oracle 9i+:自動 Undo 管理,設定 UNDO_RETENTION 目標保留秒數,引擎自動擴展/縮減 Undo Tablespace。
  • 風險:長查詢若所需 Undo 已被覆寫,拋出 ORA-01555,查詢失敗。

鎖升級與粒度

  • SQL Server:6.5 版前鎖定頁 (8KB);7.0 引入列級鎖;動態升級:列 → 頁 → 表/分區 (Lock Escalation),閾值約 5000 鎖。可用 LOCK_ESCALATION = TABLE/AUTO/DISABLE (2008+) 控制。
  • Oracle:永遠列級鎖,無鎖升級機制。鎖資訊儲存在資料區塊頭 (ITL slots),ITL 不足時動態擴展 (需空間),極少發生升級爭用。

應用開發啟示

場景SQL Server 建議Oracle 建議
高併發 OLTP啟用 RCSI (資料庫級) 讓讀不阻寫,寫不阻讀;縮短交易範圍預設 RC 已滿足大多數;長查詢注意 UNDO_RETENTION
報表/分析查詢專用報表實例 (Always On 可讀次要) 或 SNAPSHOT 隔離預設 RC 即可,不阻塞 OLTP
資料一致性要求極高SERIALIZABLE / SNAPSHOT (SI) + 衝突重試邏輯SERIALIZABLE (需應用處理 ORA-08177)
批次大量更新分批次、避免鎖升級至表級、考慮 TABLOCK 提示分批次、COMMIT 頻率平衡 Undo 產生

總結

SQL Server 以鎖為主、版本為輔,預設行為保守 (讀寫互斥),啟用 RCSI/SI 後可達類 Oracle 體驗,但版本存放於 TempDB 需容量規劃。Oracle 以純 MVCC 為核心,讀寫天然不阻塞,一致性由 Undo 保證,DBA 需管理 Undo 保留策略。無絕對優劣,唯有適配業務模式的架構選擇。 現代雲資料庫 (Azure SQL / Amazon RDS / Oracle Autonomous) 均在引擎層內建智能化並行控制,開發者更應聚焦於交易設計、隔離級別選擇、長查詢治理而非底層機制爭論。

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