---
id: 14
title: 樂觀並行控制（OCC）入門：從資料庫到鏈上執行
slug: optimistic-concurrency-control-intro
date: 2026/08/29
summary: 樂觀並行控制源自 1981 年的資料庫研究，今日成為平行 EVM 的常用骨架。本文用讀—驗證—寫三階段說明 OCC 假設，對比悲觀鎖與 MVCC，並指出區塊鏈多出的確定性與拜占庭約束。
keywords: 樂觀並行控制,OCC,讀寫集,可序列化,平行EVM
heroImage: /images/community-bg.png
---

平行 EVM 的討論裡反覆出現同一套動詞：先平行執行，再檢查衝突，不行就回滾重跑。這聽起來像鏈上原創，骨架卻來自資料庫。1981 年，H. T. Kung 與 John T. Robinson 在 ACM TODS 發表《On Optimistic Methods for Concurrency Control》，把「樂觀」寫成可分析的並行控制方法。讀懂那套邏輯，再看 Block-STM 或平行 EVM 引擎，會少很多神秘感。

本稿用資料庫視角講清 OCC 的假設與三階段，把它和悲觀鎖、MVCC 分開，然後說明區塊鏈借用這套骨架時多了哪些約束。這是理解「為什麼樂觀平行適合 EVM 相容路線」的前置課，而不是任何具體產品的參數手冊。

## 樂觀在賭什麼

傳統並行控制大量依賴鎖：存取前先加鎖，防止別人同時改你正在讀的資料。鎖能保證正確，但維護鎖表、偵測死鎖、長事務佔鎖拖垮佇列，都會在高並行下變成明顯開銷。OCC 的反直覺提議是：若大多數事務的讀寫集合其實並不重疊，不如先讓它們跑，把衝突檢查推遲到提交前夕，避免為「可能永遠不會發生的衝突」支付鎖成本。論文把回退（backup）當作主要控制手段——「樂觀」指的是寄望於衝突稀疏。

這不是否認衝突存在，而是轉移處理時機：從執行前預防，改為執行後（或臨近提交時）驗證。時機一變，系統設計的主要矛盾就從「如何精細加鎖」變成「如何便宜地偵測衝突、如何縮小重做的範圍」。

## 讀、驗證、寫：三階段骨架

經典 OCC 把事務拆成三個階段。

讀階段：事務自由讀取資料庫，寫入只落在私有工作區，不立即污染共享狀態。對觀察者而言，尚未驗證事務的副作用還不可見，或僅以隔離方式存在。

驗證階段：事務取得時間戳或序號，系統檢查其讀集是否仍然有效——是否在讀取之後被「按順序應排在前面」的其他事務改寫。若讀集過期，驗證失敗，事務中止並重來。驗證要回答的問題本質是可序列化：平行執行的交錯，能否等價於某個串列順序。

寫階段：驗證通過後，把私有寫集合併進共享資料庫。論文還區分串列驗證與平行驗證：前者把驗證與寫入綁成更強的原子步驟，實作簡單；後者允許更多並行，但需要額外機制保證不會寫出互相矛盾的提交。

把這三個階段映射到區塊鏈平行執行，幾乎是一一對應：交易在推測狀態下執行並收集讀寫集；按區塊內既定順序驗證；通過者提交狀態，失敗者依依賴關係重新執行。名稱可以叫 STM、Block-STM 或「樂觀平行 EVM」，骨架仍是 OCC。

## 悲觀鎖為何顯得重

兩階段鎖（2PL）是關聯式資料庫裡最經典的悲觀方案：事務持鎖只增不減直到結束。正確性好講，代價也好懂——鎖記憶體、死鎖、佇列頭阻塞。競爭低時，2PL 的「預防稅」可能高於 OCC 偶發的重做；競爭高時，OCC 的重做風暴可能反超鎖的成本。因此 OCC 從一開始就被標成「低爭用更划算」。鏈上的翻譯是：當區塊內交易的讀寫集重疊少，樂觀平行賺得多；當大家都打同一個 AMM 池，樂觀平行必須靠工程把重新執行限制住，否則數字會很難看。

這也解釋了為何效能披露必須標明負載類型與測試條件。實驗室裡大量無關的轉帳，與主網高峰期的 DEX 路由交易，衝突結構完全不同；同一套 OCC 引擎可以給出差一個數量級的觀感。

## MVCC：相關，但不是同一個旋鈕

多版本並行控制（MVCC）常與 OCC 並列出現，卻回答不同的問題。MVCC 讓讀者看到一致性快照，讀者不阻塞寫者；核心是版本儲存與可見性規則。OCC 的核心則是驗證失敗時該怎麼辦。二者可以疊加：用多版本降低讀寫互相踩踏，再用樂觀驗證決定寫寫衝突時由誰提交。Hekaton、Silo、TicToc 等系統展示了時間戳、去中心化驗證、延遲分配序號等變體，共同點是承認「純悲觀鎖在多核上太貴」，用版本與延遲驗證換取吞吐量。

對鏈上工程師而言，這層澄清有助於閱讀論文與專案文件：有人說「我們用了 MVCC」，可能只是在描述狀態表示；真正決定平行 EVM 行為的，往往是驗證規則與重新執行的排程——那是 OCC 家族的問題。

## 區塊鏈多出來的規則

資料庫 OCC 通常假設失敗可以本地重試，客戶端能感知中止。區塊鏈多了兩條硬約束。

第一，全網確定性重放。所有誠實節點對同一區塊必須得到同一最終狀態。樂觀執行可以在節點內部平行，但提交結果必須收斂到與規範順序等價的狀態；不能出現「這台機器因為排程運氣不同而提交了另一套寫集」。這迫使實作把「預設順序」或「規範序號」寫進協議，而不是讓執行緒排程成為語意的一部分。

第二，拜占庭環境。不能假設單一執行者誠實。節點可能說謊、省略、故意製造衝突以拖慢對手。因此平行執行引擎通常嵌在更大的共識與驗證流程裡：順序先由共識確定，執行層負責高效且確定地算出狀態根；輕客戶端與全節點依賴的是可驗證的最終狀態，而不是某次樂觀路徑的中間猜測。

Aptos 團隊在 Block-STM 相關論文中，把引擎明確放在 STM 與 OCC 的傳統上，並強調把「排序」從詛咒變成可利用的效能條件：順序給定後，平行只是加速收斂到該順序的手段。這個說法對平行 EVM 同樣適用——EVM 交易本就活在「區塊內有序」的世界裡，OCC 是在服從該順序的前提下搶多核，而不是取消順序。

## 讀寫集：抽象簡單，工程不簡單

教科書裡的讀集、寫集，在 EVM 裡對應到帳戶餘額、nonce、儲存槽、偶發的日誌與退款副作用等。粒度太粗（把整個合約當成一個鍵）會製造假衝突，平行度被白白吃掉；粒度太細會讓追蹤與驗證成本上升。動態跳轉、外部呼叫、代理模式讓靜態預先分析不完整，這正是 EVM 難以採用確定性預先宣告的原因，也是為什麼在執行環境中收集讀寫集成為預設策略。

衝突後是重跑單筆、重跑依賴閉包，還是整批作廢，決定尾端延遲。優秀的 OCC 實作把「驗證失敗」當成可預期的熱路徑來最佳化，而不是異常分支。這些細節屬於具體引擎設計；對這篇入門文而言，只需要建立判斷力：看到平行 EVM 宣稱高吞吐量，先問衝突率假設與重新執行策略，再問測試網或基準條件。

## 從直覺到下一篇定位

用資料庫 OCC 來讀區塊鏈執行，是為了把討論從口號拉回可檢驗的機制：假設是什麼、驗證查什麼、失敗成本由誰承擔。Bitroot 以及其他樂觀平行 EVM 專案，差異往往不在「是否採用 OCC」——而在讀寫集如何擷取、衝突如何分層偵測、共識是否與執行流水線解耦。下一篇會把鏡頭對準 Bitroot：在擴容地圖與三條平行路線上，它選了哪一格、邊界在哪裡，以及哪些承諾仍應標成測試條件下的工程目標。

## 延伸閱讀

- 前置閱讀：[《平行執行的三條路線：確定性排程、樂觀 OCC 與物件模型》](/zh-Hant/blog/parallel-execution-approaches)
- 下一篇：[《Bitroot 定位：樂觀平行 EVM 的 Layer 1 邊界》](/zh-Hant/blog/bitroot-positioning)
- 相關閱讀：[《Bitroot 平行化 EVM 技術解析：樂觀平行化》](/zh-Hant/blog/bitrootevm-)、[《效能指標詞典：TPS、BPS、確認延遲、最終性、衝突率》](/zh-Hant/blog/performance-metrics-glossary)
