Java-58 深入淺出 分布式服務 ACID 三階段提交3PC 對比2PC

點一下關注吧!!!非常感謝!!持續更新!!!

🚀 AI篇持續更新中!(長期更新)

目前2025年06月16日更新到:
AI煉丹日志-29 - 字節跳動 DeerFlow 深度研究框斜體樣式架 私有部署 測試上手 架構研究,持續打造實用AI工具指南!📐🤖

💻 Java篇正式開啟!(300篇)

目前2025年06月26日更新到:
Java-55 深入淺出 分布式服務 分布式一致性 強一致、弱一致、單調讀一致、最終一致
MyBatis 已完結,Spring 已完結,Nginx已完結,Tomcat已完結,分布式服務正在更新!深入淺出助你打牢基礎!

📊 大數據板塊已完成多項干貨更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余項核心組件,覆蓋離線+實時數倉全棧!
目前2025年06月13日更新到:
大數據-278 Spark MLib - 基礎介紹 機器學習算法 梯度提升樹 GBDT案例 詳解

請添加圖片描述

一致性3PC(Three-Phase Commit)

概述

3PC(Three-Phase Commit)全稱為三階段提交協議,是二階段提交協議(2PC)的改進版本。3PC將2PC的提交事務請求過程進一步細分為兩個階段,最終形成由CanCommit、PreCommit和doCommit三個階段組成的分布式事務處理協議。

協議階段詳解

1. CanCommit階段(詢問階段)

  • 協調者向所有參與者發送CanCommit請求
  • 參與者檢查自身狀態,判斷是否可以執行事務
  • 參與者回復Yes/No響應(ACK/NACK)
  • 協調者根據響應決定是否進入下一階段

2. PreCommit階段(準備階段)

  • 若全部參與者回復Yes,協調者發送PreCommit請求
  • 參與者執行事務操作但不提交,寫入undo/redo日志
  • 參與者鎖定相關資源,確保事務可回滾
  • 參與者回復Ack確認準備完成

3. doCommit階段(提交階段)

  • 協調者收到所有Ack后發送doCommit請求
  • 參與者正式提交事務
  • 參與者釋放資源鎖
  • 參與者回復Ack確認提交完成

改進優勢

與2PC相比,3PC的主要改進包括:

  1. 增加了CanCommit階段,提前驗證參與者狀態
  2. 降低了阻塞風險(引入超時機制)
  3. 提高了系統可用性(部分故障可繼續運行)
  4. 減少了協調者單點故障的影響

應用場景

3PC適用于以下分布式系統場景:

  • 數據庫集群事務處理
  • 跨服務的事務協調
  • 微服務架構中的Saga模式
  • 需要較高可用性的分布式系統

局限性

盡管3PC有所改進,但仍存在以下問題:

  • 網絡分區時可能導致數據不一致
  • 實現復雜度高于2PC
  • 性能開銷相對較大
  • 不能完全解決所有分布式一致性問題

在這里插入圖片描述

階段一

● 事務詢問:協調者向所有參與者發送一個包含事務內容的canCommit請求,詢問是否可以執行事務提交操作,并開始等待各參與者的響應
● 各參與者向協調者反饋事務詢問的響應:參與者在接收到來自協調者的包含了事務內容的canCommit請求后,在正常情況下,如果自身認為可以順利執行事務,則反饋Yes,并進入預備狀態,否則反饋No響應。

在這里插入圖片描述

階段二

PreCommit
協調者在得到參與者的響應之后,會根據結果有2種執行操作的情況:執行事務預提交,或者中斷事務。
假如所有參與者反饋的都是Yes,那么就會執行事務預提交。

● 發送預提交請求:協調者向所有參與節點發出 preCommit 請求,并進入 prepared 階段
● 事務預提交:參與者接收到 preCommit 請求后,會執行事務操作,并將 Undo、Redo 信息記錄到事務日志中
● 各參與協調者反饋事務執行的結果:若參與者執行成功了事務操作,那么反饋ACK。若任一參與者反饋了No的時候,或者超時之后,協調者無法收到所有參與者的響應,則中斷事務

中斷事務也分為兩個步驟:
● 發送中斷請求:協調者向所有參與者發出 abort 請求
● 中斷事務:無論是收到來自協調者的abort請求或者等待協調者請求過程中超時,參與者都會中斷事務

在這里插入圖片描述

階段三

doCommit

該階段做真正的事務提交或者完成事務回滾,所有會出現兩種情況:

情況一 執行事務提交

● 發送提交請求:進入這一階段,假設協調者處于正常工作狀態,并且它接收到了來自所有參與者ACK響應,那么他將從預提交狀態轉換為提交狀態,并向所有參與者發送doCommit請求
● 事務提交:參與者收到doCommit請求后,會正式執行事務提交操作,并在完成提交之后釋放整個事務執行過程中占用的事務資源。
● 反饋事務提交結果:參與者在完成事務提交后,向協調者發送ACK響應
● 完成事務:協調者接收到所有參與者反饋的ACK消息之后,完成事務。

情況二 中斷事務

● 發送中斷請求:協調者向所有的參與者節點發送abort請求。
● 事務回滾:參與者收到abort請求后,會根據記錄的Undo信息來執行事務回滾,并在完成回滾之后釋放整個事務執行期間占用的資源
● 反饋事務回滾結果:參與者在完成事務回滾后,向協調者發送ACK消息
● 中斷事務:協調者接收到所有參與者反饋的ACK消息后,中斷事務

注意:一旦進入階段三,可能會出現2種故障:
● 協調者出現問題
● 協調者和參與者之間的網絡故障

如果出現任意一種情況,最終都會導致參與者無法收到 doCommit 請求 或者 abort 請求,針對這種情況,參與者都會在超時之后,繼續進行事務提交

2PC對比3PC

超時機制改進

在2PC(兩階段提交)協議中,只有協調者擁有超時機制。這意味著當協調者在規定時間內沒有收到參與者的響應時,會默認事務執行失敗。然而,3PC(三階段提交)對此進行了重要改進:

  1. 參與者超時機制:
    • 每個參與者都設置了超時計時器
    • 如果在CanCommit或PreCommit階段長時間未收到協調者指令(如網絡分區或協調者故障)
    • 參與者會在超時后自動執行本地Commit操作釋放資源

實際應用場景示例:
當電商系統處理分布式訂單時,如果支付服務(參與者)在PreCommit階段與訂單服務(協調者)失去連接,支付服務會在超時后自動提交本地事務,避免資金長時間凍結。

三階段設計優勢

3PC通過三個階段的設計提供了更好的可靠性:

  1. CanCommit階段:

    • 協調者詢問參與者是否具備執行事務的條件
    • 參與者檢查資源可用性但不鎖定資源
    • 類似于"預檢查"階段
  2. PreCommit階段:

    • 核心緩沖階段
    • 協調者在收到所有參與者的Yes響應后發送PreCommit請求
    • 參與者執行事務操作但暫不提交
    • 在此階段確保所有參與者狀態一致
  3. DoCommit階段:

    • 最終提交階段
    • 協調者確認所有參與者完成PreCommit后發送提交指令

分階段好處示例:
在銀行轉賬系統中,PreCommit階段可以確保所有賬戶的余額檢查通過且金額已臨時扣減,才會進入最終提交階段,避免部分賬戶扣款成功而其他賬戶失敗的情況。

局限性

盡管有上述改進,3PC仍存在以下問題:

  1. 數據不一致的可能性:

    • 在DoCommit階段若發生網絡分區
    • 部分參與者可能收不到提交指令
    • 導致系統部分節點已提交而其他節點未提交
  2. 性能損耗:

    • 額外的通信階段增加了延遲
    • 不適合對延遲敏感的應用場景
  3. 實現復雜度:

    • 需要更復雜的狀態機來處理各階段異常
    • 增加了系統開發和維護成本

實際案例:
在分布式數據庫系統中,即使使用3PC,仍然需要額外的補償機制(如人工干預或自動修復程序)來處理極端情況下出現的數據不一致問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86960.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86960.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86960.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

matplotlib 繪制餅圖

1、功能介紹: 使用 python 的 matplotlib 庫來創建一個簡單的餅圖。 2、代碼部分: import matplotlib.pyplot as plt# 示例數據 labels [A, B, C, D, E] # 類別標簽 sizes [15, 30, 45, 5, 5] # 每個類別對應的數值(百分比&#xff09…

用Rust寫平衡三進制除法器

1、除法的本質 除法的本質是減法,也就是一個大的數減去一個小的數,比如:10/2,也就是10-2-2-2-2-20,所以商5余0,10/3,也就是10-3-3-31,所以商3余1,這也是很常見的方法,但如…

深入探索WordPress Multisite:構建與管理多站點網絡

隨著互聯網的快速發展,越來越多的企業和個人開始使用內容管理系統來搭建和維護自己的網站。WordPress作為全球最受歡迎的CMS之一,因其強大的功能和靈活性,成為了許多網站管理員的首選平臺。而在一些特定需求的場景下,WordPress Mu…

.Net Core 獲取文件路徑

在 .NET Core 中獲取文件路徑的方法取決于你要獲取的文件的位置和上下文。這里將介紹幾種常見的方式來獲取文件路徑。 1. 獲取當前工作目錄 你可以使用 Directory.GetCurrentDirectory() 方法來獲取當前工作目錄的路徑: using System; using System.IO; class P…

順序表整理和單項鏈表01 day20

二:各個主要函數 一:CreatSeqList SeqList *CreateSeqList(int len); -------------------------------------------------------------/*** brief Create a Seq List object 創建一個順序表** param n 是順序表的大小* return SeqList* 指向順序表的…

電商導購app平臺的緩存策略與性能優化方案:架構師的實踐經驗

電商導購app平臺的緩存策略與性能優化方案:架構師的實踐經驗 大家好,我是阿可,微賺淘客系統及省賺客APP創始人,是個冬天不穿秋褲,天冷也要風度的程序猿! 緩存策略的重要性 在電商導購APP平臺中&#xff…

學習C++、QT---12(C++的繼承、權限對繼承的影響)

每日一言 你的價值,由你自己定義,無需他人評判。 C的繼承 直接上案例 繼承是什么意思呢,就是我本來這個類我叫他基類、我希望創建我的下一個類有我這之前的類的屬性和方法,那么我如果不用繼承的話,就需要多寫很多一樣…

(6)Wireshark的TCP包詳解-上篇

1.簡介 上一篇中通過介紹和講解,應該知道要講解和介紹的內容在哪里了吧,沒錯就是介紹OSI七層模型的傳輸層。因為只有它建立主機端到端的連接如:TCP、UDP。 2.TCP是什么? tcp是工作在傳輸層,也就是網絡層上一層的協議。 它是面…

太極八卦羅盤JS繪制

LeaferJS 是一款好用的 Canvas 引擎,通過LeaferJS繪制羅盤案例. https://www.leaferjs.com/ui/guide/ 示例 太極八卦羅盤 直接上代碼 <template><div id"LuoPan"></div><div id"info"><p>屏幕寬度: {{ screenWidth }}px<…

Python開源項目月排行 2025年5月

#2025年5月2025年6月1日1scrapy一個開源的、基于 Python 的高性能網絡爬蟲和數據抓取框架。Scrapy 項目最初由倫敦的網絡聚合和電子商務公司 Mydeco 的員工以及烏拉圭蒙得維的亞的網絡咨詢公司 Insophia 的開發者共同創建。目前&#xff0c;Scrapy 由 Zyte&#xff08;原名 Scr…

Debezium日常分享系列之:在 Kubernetes 中使用 Debezium 的 CDC

Debezium日常分享系列之&#xff1a;在 Kubernetes 中使用 Debezium 的 CDC 架構源數據庫創建數據庫憑證密鑰Debezium 自定義鏡像構建并推送鏡像Kafka Connect 集群Debezium Postgres 連接器Debezium 創建的 Kafka 主題 Debezium 是一個開源的分布式變更數據捕獲 (CDC) 平臺。D…

tf serving和torch serve哪個耗時更低

TensorFlow Serving&#xff08;TF Serving&#xff09;和 TorchServe 的耗時對比需結合具體場景&#xff08;如硬件配置、模型類型、優化策略等&#xff09;&#xff0c;以下從多維度分析兩者的性能差異及適用場景。 ?? 1. 標準性能基準對比 根據公開壓測數據&#xff08;…

Java面試寶典:基礎六

133. 二進制小數點位移 答案:C(乘以2) 解析: 原理:二進制小數點右移一位等價于乘以 (2^1)(左移則除以 (2))。示例: 101.1(5.5)右移 → 1011(11)驗證:(5.5 \times 2 = 11)說明:位移前:1 0 1 . 1 (值 = 2+2?+2? = 5.5) 位移后:1 0 1 1 . (值 = 2+2+2? =…

04-React中綁定this并給函數傳參的幾種方式

前言綁定 this 的方式一&#xff1a;bind()綁定 this 并給函數傳參 的方式二&#xff1a;構造函數里設置 bind()綁定 this 并給函數傳參 的方式三&#xff1a;箭頭函數【薦】 前言 我們先來看下面這段代碼&#xff1a; components/MyComponent.jsx import React from "…

Docker拉取不兼容的鏡像解決辦法

錯誤提示如下&#xff1a; WARNING: The requested images platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested295ef35cfefe0dce6904e017e89218695d9a9c092b45496218f4476357be4f9c 這個警告表明你…

android14 未充電狀態電量低于15%彈框提示 10%直接關機

上層接收電量變化廣播&#xff0c;添加未充電判斷&#xff0c;做出彈框或關機動作 SystemUI\src\com\android\systemui\power\PowerUI.java Overridepublic void onReceive(Context context, Intent intent) {String action intent.getAction();if (PowerManager.ACTION_POWE…

ASP.NET Core 中 Kestrel 的應用及在前后端分離項目中的角色

目錄 一、Kestrel 基礎&#xff1a;輕量級且高性能的 Web 服務器 二、前后端分離項目架構&#xff1a;Vue、.NET Core API、Nginx 與 Kestrel 2.1 交互流程圖 2.2 流程詳解 三、Kestrel 在架構中的核心作用 四、launchSettings.json 與 Kestrel 配置的關系及底層機制 4.1…

Kotlin 退出循環總結

文章目錄 Kotlin 退出循環總結for循環forEach()嵌套for循環lambda函數inline函數 Kotlin 退出循環總結 for循環 for ((index, value) in list.withIndex()) {if (value "c") {break // 退出循環}println("$index - $value") }// 0 - a // 1 - bfo…

再看C語言

目錄 與Java的差異化 編程范式 跨平臺 編譯過程 包管理 基本類型 內存結構 重點掌握 進制、字節與計算 指針 結構體 關鍵詞 動態內存 模塊化 高級特性 動態鏈接 虛擬內存 打包編譯 并發編程 現在需要參與到存儲軟件開發工作&#xff0c;存儲層比較接近OS系統…

機器學習入門 | 訓練、推理與其他機器學習活動(預處理、測試與評估)

在訓練階段&#xff0c;訓練算法通過優化目標/損失函數在訓練數據集上的表現&#xff0c;不斷更新模型參數θ。在監督學習場景中&#xff0c;訓練數據集由輸入-標簽對&#xff08;真實輸出值&#xff09;組成。目標函數應當獎勵模型根據訓練輸入成功預測真實輸出的行為&#xf…