分散式交易與兩階段提交 (Distributed Transactions & 2PC)

★★★★Draft

FromDDIAMicroservices Patterns

📚 From the Books

分散式交易與兩階段提交 (Distributed Transactions & 2PC)ConceptConsistency & Consensus

跨多個節點的交易,要嘛全部提交、要嘛全部中止,不能部分成功。單機靠儲存引擎寫 WAL 就能原子提交;多節點就得有協定來協調——這就是原子提交問題,經典解是兩階段提交 (2PC)

🧠 Core Ideas

TIP

2PC 引入一個協調者 (coordinator),分兩階段:prepare(問所有參與者「你能提交嗎」)→ commit/abort(收齊 yes 才提交)。參與者投 yes 是不可撤回的承諾;協調者把決定寫入磁碟那一刻是提交點。這兩個「不可逆時刻」共同保證原子性。

⚖️ 致命弱點:協調者故障

疑問狀態 (In-Doubt) 與阻塞
  • 若協調者在「參與者都投 yes」之後、「發出 commit/abort」之前當機,參與者陷入疑問狀態
    • 不能單方面中止(別人可能已收到 commit 提交了)。
    • 不能單方面提交(別人可能已收到 abort 中止了)。
    • 問別的參與者也沒用(大家一樣不知道)。
  • 唯一解法:等協調者恢復。等待期間交易持有的行級鎖不釋放,阻塞所有想碰這些行的交易——故障可能波及整個資料庫。
3PC 為什麼救不了
  • 三階段提交加逾時讓參與者能自行決定、避免阻塞,但它假設網路延遲有界、節點回應時間有界
  • 真實網路延遲不可預測(GC 暫停、擁塞都會讓節點「看起來像掛了」),這假設不成立,3PC 可能做出不安全決定。所以 2PC 仍是主流。

⚖️ XA 與異質分散式交易

XA 標準與它的實務問題
  • XA(eXtended Architecture)是跨異質技術(不同廠商 DB、DB 與訊息代理間)實作 2PC 的標準 C API。PostgreSQL、MySQL、多數訊息代理都支援。
  • 問題:協調者是單點故障有狀態(要持久化交易日誌,不能無狀態水平擴展);相容性限制了各 DB 的高階最佳化;諷刺的是——它為容錯而生,故障時的鎖定效應反而把單一系統的故障擴散到所有參與系統
  • 許多雲端服務因此乾脆不實作 XA。
微服務的替代:Saga
  • 微服務世界常放棄跨服務的 2PC,改用 Saga:把長交易拆成一串本地交易,每步失敗就跑補償交易 (compensating transaction) 回滾已完成的步驟。
  • 代價是只有最終一致、沒有隔離性,要自己處理中間狀態——但避開了 2PC 的跨服務鎖定與阻塞。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading

🔗 Dive Deeper