支援成千上萬使用者同時存取而不犧牲正確性,是關聯式資料庫的核心價值。SQL Server 與 Oracle 作為兩大商業資料庫巨頭,在並行控制上採取了截然不同的架構哲學:SQL Server 採用悲觀鎖為主、鎖升級機制;Oracle 採用樂觀多版本並行控制 (MVCC)。本文深度解析兩者差異本質,並給出應用層應對策略。
| 維度 | SQL Server (預設) | Oracle |
|---|---|---|
| 並行模型 | 悲觀鎖 | 樂觀 MVCC (多版本並行控制) |
| 讀取是否阻塞寫入 | 是(共享鎖 vs 排他鎖) | 否(讀取不加鎖,讀取一致性快照) |
| 寫入是否阻塞讀取 | 是(排他鎖阻塞共享鎖) | 否(寫入產生新版本,讀取舊版本) |
| 一致性實現 | 鎖 + 隔離等級 | Undo Segment + SCN (系統變更號) |
| 鎖粒度 | Row → Page → Table (自動升級) | Row Level Only (無升級) |
| 死鎖處理 | 死鎖監視器週期性檢測,犧牲受害者 | 等待圖檢測,犧牲受害者 |
| 長時間查詢影響 | 持有鎖久 → 阻塞並發、鎖升級風險 | Undo 保留壓力、ORA-01555 風險 |
-- 鎖層級由細到粗
ROW (RID/KEY) → PAGE (8KB) → OBJECT (TABLE) → DATABASE
-- 意圖鎖 (Intent Locks) 用於層級協調
IS (Intent Shared) → S
IX (Intent Exclusive) → X, IX, SIX
SIX (Shared with Intent Exclusive) → S + IX
-- 會話 1:開啟交易更新單行
BEGIN TRAN;
UPDATE Production.Product SET ListPrice = ListPrice * 1.05 WHERE ProductID = 707;
-- 未 COMMIT/ROLLBACK
-- 會話 2:查詢同表其他行 → 被阻塞!
SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID = 708;
-- 原因:預設 READ COMMITTED 隔離級別需申請共享鎖 (S),
-- 但會話 1 在頁/表層持有意圖排他鎖 (IX) 或已升級為表排他鎖 (X)
ALTER DATABASE YourDB SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE;
| 場景 | SQL Server 對策 | Oracle 對策 |
|---|---|---|
| 高併發 OLTP 更新熱點行 | 縮短交易、行鎖索引覆蓋、考慮 RCSI、應用層重試邏輯 | 縮短交易、ITL 槽位預留 (INITRANS)、避免熱點區塊爭用 |
| 長時間報表查詢並發 OLTP | 啟用 RCSI、資料庫快照、可用性群組次要副本讀取 | Materialized View、Result Cache、Active Data Guard 實時查詢 |
| 批次大量更新/刪除 | 分批提交 (每 1000-5000 行)、TABLOCK 提示減少鎖升級、離線維護窗口 | 分批提交、Parallel DML、NOLOGGING + 事後備份 |
| 死鎖頻發 | 統一存取順序、行版本控制 (RCSI/SI)、死鎖圖分析 (xEvent) | 統一存取順序、SELECT FOR UPDATE NOWAIT/SKIP LOCKED |
| 應用移植遷移 | 注意:Oracle 無鎖升級,但長查詢吃 Undo;SQL Server 預設讀阻塞寫 | 注意:SQL Server 需顯式啟用 RCSI 才能讀不阻塞寫 |
| ANSI 標準 | SQL Server 實現 | Oracle 實現 |
|---|---|---|
| READ UNCOMMITTED | NOLOCK / READ UNCOMMITTED (髒讀) | 不支援 (唯讀一致性) |
| READ COMMITTED | 預設:共享鎖 (阻塞) / RCSI:版本存放區 | 預設:Statement-Level 一致性 (Undo) |
| REPEATABLE READ | 交易期間持有共享鎖至結束 | 不支援 (僅 SERIALIZABLE) |
| SNAPSHOT (SI) | 交易級快照,啟用 `ALLOW_SNAPSHOT_ISOLATION` | 不支援 (但 SERIALIZABLE 類似) |
| SERIALIZABLE | 範圍鎖 (Key-Range Lock),效能極差 | Serializable 隔離,可能 ORA-08177 (無法序列化) |
SQL Server:鎖機制成熟、可預測、工具鏈豐富。關鍵在於——縮短交易、善用索引避免掃描、評估 RCSI 收益。
Oracle:MVCC 架構天然讀寫不阻塞,適合長查詢與高併發混合負載。關鍵在於——Undo 空間規劃、ITL 預留、避免長交易佔用 Undo。
理解兩者並行控制的本質差異,才能在架構選型、應用開發、效能調優、故障排查中做出正確決策。沒有銀彈,只有適配場景的工程判斷。