主頁 > 軟體設計 > 分布式事務實戰方案匯總

分布式事務實戰方案匯總

2021-03-03 19:09:16 軟體設計

分布式事務實戰方案匯總

  • 1. 最終一致性
    • 1.1 本地事務表 + 輪詢補償
      • 互動流程
      • 場景:重構業務新老系統雙寫庫同步
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
      • 場景:第三方認證核驗
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
    • 1.2 本地事務表 + 事務訊息
      • 互動流程
      • 場景:分庫分表路由欄位系結
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
    • 1.3 TCC(Try-Commit-Cancel)
      • 互動流程
      • 場景:積分商品兌換
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
      • 場景:廣告任務結算
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
      • 場景:運營活動抽獎
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
  • 2. 弱一致性
    • 2.1 最大努力通知 + 訊息重試控制
      • 場景:資料變更同步下游業務方
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
      • 場景:資料變更廣播下游業務方
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
    • 2.2 戰略放棄 + 報警 + 人工修復
      • 場景:秒殺庫存回滾
        • 專案背景
        • 分布式事務
        • 設計方案
        • 場景Q&A
  • 3. 總結
    • 3.1 分布式角色
    • 3.2 技術保證
    • 3.2 強弱一致選擇
    • 3.3 冪等&防重
    • 3.4 盡早干預&補償一致
  • 5. 參考

1. 最終一致性

1.1 本地事務表 + 輪詢補償

互動流程

在這里插入圖片描述

  • commit DB事務提交階段 本地客戶端向DB進行事務提交,此時需要將業務資料和記錄訊息事務狀態的資訊表同時實作本地事務,此時標記訊息事務狀態為UN_SEND未發送或未完成狀態,此時MQ未發送
  • ack DB確認階段 回傳DB事務提交成功或失敗狀態
  • commit MQ事務提交階段 客戶端發起MQ發送請求
  • update 本地事務表更新階段 根據MQ發送結果進行本地訊息事務表狀態更新,成功則更新為SEND發送成功或發送完畢
  • MQ補償 本地訊息事務表定時輪詢 對未發送成功訊息事務進行補償發送,實作分布式事務的最終一致

場景:重構業務新老系統雙寫庫同步

在這里插入圖片描述

專案背景

這是一個重構系統新老系統同時服役切量遷移的業務場景,老系統正在線上服役為各業務方提供介面查詢功能,新系統重構完成后需要對接接入,呼叫流量要陸續從老系統切換到新系統,最終老系統迭代下線,

分布式事務

需要解決的分布式事務問題就是,雙系統的資料是異構、分散的,線上不可停量,需要陸續切換完成,因此需要事先將老庫存量資料洗入新庫,此程序中增量資料寫入是存在的,但是最終新老庫是相對一致和統一的,該場景需要解決的是資料雙庫的雙寫問題

設計方案

系統寫操作讀操作呼叫方
老系統異步寫(MQ)讀(冗余查)歷史存量渠道
新系統同步寫新業務渠道/歷史存量切換渠道

場景Q&A

  • Q:如何保證雙庫雙寫?

    A: 同步寫辛庫,MQ異步寫老庫

    • 本地事務 + 訊息事務表
      業務資料持久化開啟資料庫本地事務,該事務中記錄業務資料同步狀態資訊
    • 確保本地事務一定成功,不保證異步MQ事務
      資料庫事務成功后再發送寫老庫的MQ,保證本地事務一定完成才會觸發MQ發送,這樣確保本地事務一定成功,MQ可能成功也可能失敗
    • 重試MQ事務狀態,最終一致
      如果MQ事務失敗,通過定時任務輪詢進行重發驅動,最終一致
  • Q:異步MQ寫,延遲問題如何解決?

    A: 增加冗余查詢
    增加冗余對另一庫的冗余查詢進行Double Check,由于呼叫方幾乎不可能同時使用新老系統做業務,因此延遲時間取決于MQ異步消費寫的速度,如果場景比較復雜要確保絕對一致可以增加該處理方式

  • Q:雙寫程序中多個MQ如何保證順序、防重等問題?

    A: 業務時間 + 業務ID

    • (1)同一個業務ID代表一個同一筆業務,可以依此進行業務防重處理
    訊息業務ID業務時間消費時間處理邏輯
    IDTT執行
    IDTT+1防重不處理
    • (2)同一個業務ID的基礎上增加業務時間,可以依此保證業務資料的實時重繪

    業務時間、消費時間同序

    訊息業務ID業務時間消費時間處理邏輯
    IDTT執行
    IDT+1T+1執行(覆寫)

    業務時間、消費時間亂序

    訊息業務ID業務時間消費時間處理邏輯
    IDTT+1拋棄(業務時間較早)
    IDT+1T執行
    • (3)不同業務ID的基礎上增加業務時間,可以依此保證不同業務資料的按照業務時間重繪
    訊息業務ID業務時間消費時間處理邏輯
    IDT+1T+1執行(業務時間較新)
    ID+XTT拋棄(業務時間較早)

場景:第三方認證核驗

在這里插入圖片描述

專案背景

這是一個認證系統以來外部核驗系統進行用戶身份鑒權的場景,即認證系統記錄認證發起記錄,并請求到外部的核驗系統發起一筆核驗請求,用戶在核驗系統確認后核驗結果回傳到認證系統確認用戶的真實資料狀態,

分布式事務

該流程中認證系統是一個本地系統,存放用戶發起的認證流水資訊和核驗狀態,依賴外部核驗系統回傳該筆認證記錄的核驗狀態,由于核驗程序是異步的,用戶可以選擇任意時間完成或者永遠不完成,需要保證每次認證流程只有一筆業務發起,而且需要根據業務時間進行核驗流程的超時進行強制取消或者補償查詢對齊核驗狀態等,需要解決的分布式事務是認證流水、核驗結果的一致性

設計方案

資料系統事務正向事務逆向事務
認證流水資料本地系統本地事務本地事務2PC保證定時任務,超時關閉流程
核驗狀態資料外部系統分布式事務聯同本地事務提交 / 定時任務驅動補償提交外部系統控制
  • 正向流程
<style>#mermaid-svg-Xunb4T56sEIHDLuz .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-Xunb4T56sEIHDLuz .label text{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .node rect,#mermaid-svg-Xunb4T56sEIHDLuz .node circle,#mermaid-svg-Xunb4T56sEIHDLuz .node ellipse,#mermaid-svg-Xunb4T56sEIHDLuz .node polygon,#mermaid-svg-Xunb4T56sEIHDLuz .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-Xunb4T56sEIHDLuz .node .label{text-align:center;fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .node.clickable{cursor:pointer}#mermaid-svg-Xunb4T56sEIHDLuz .arrowheadPath{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-Xunb4T56sEIHDLuz .flowchart-link{stroke:#333;fill:none}#mermaid-svg-Xunb4T56sEIHDLuz .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-Xunb4T56sEIHDLuz .edgeLabel rect{opacity:0.9}#mermaid-svg-Xunb4T56sEIHDLuz .edgeLabel span{color:#333}#mermaid-svg-Xunb4T56sEIHDLuz .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-Xunb4T56sEIHDLuz .cluster text{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-Xunb4T56sEIHDLuz .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-Xunb4T56sEIHDLuz text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-Xunb4T56sEIHDLuz .actor-line{stroke:grey}#mermaid-svg-Xunb4T56sEIHDLuz .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-Xunb4T56sEIHDLuz .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-Xunb4T56sEIHDLuz #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-Xunb4T56sEIHDLuz .sequenceNumber{fill:#fff}#mermaid-svg-Xunb4T56sEIHDLuz #sequencenumber{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz #crosshead path{fill:#333;stroke:#333}#mermaid-svg-Xunb4T56sEIHDLuz .messageText{fill:#333;stroke:#333}#mermaid-svg-Xunb4T56sEIHDLuz .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-Xunb4T56sEIHDLuz .labelText,#mermaid-svg-Xunb4T56sEIHDLuz .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-Xunb4T56sEIHDLuz .loopText,#mermaid-svg-Xunb4T56sEIHDLuz .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-Xunb4T56sEIHDLuz .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-Xunb4T56sEIHDLuz .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-Xunb4T56sEIHDLuz .noteText,#mermaid-svg-Xunb4T56sEIHDLuz .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-Xunb4T56sEIHDLuz .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-Xunb4T56sEIHDLuz .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-Xunb4T56sEIHDLuz .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-Xunb4T56sEIHDLuz .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz .section{stroke:none;opacity:0.2}#mermaid-svg-Xunb4T56sEIHDLuz .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-Xunb4T56sEIHDLuz .section2{fill:#fff400}#mermaid-svg-Xunb4T56sEIHDLuz .section1,#mermaid-svg-Xunb4T56sEIHDLuz .section3{fill:#fff;opacity:0.2}#mermaid-svg-Xunb4T56sEIHDLuz .sectionTitle0{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .sectionTitle1{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .sectionTitle2{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .sectionTitle3{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-Xunb4T56sEIHDLuz .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz .grid path{stroke-width:0}#mermaid-svg-Xunb4T56sEIHDLuz .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-Xunb4T56sEIHDLuz .task{stroke-width:2}#mermaid-svg-Xunb4T56sEIHDLuz .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz .taskText:not([font-size]){font-size:11px}#mermaid-svg-Xunb4T56sEIHDLuz .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-Xunb4T56sEIHDLuz .task.clickable{cursor:pointer}#mermaid-svg-Xunb4T56sEIHDLuz .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Xunb4T56sEIHDLuz .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Xunb4T56sEIHDLuz .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Xunb4T56sEIHDLuz .taskText0,#mermaid-svg-Xunb4T56sEIHDLuz .taskText1,#mermaid-svg-Xunb4T56sEIHDLuz .taskText2,#mermaid-svg-Xunb4T56sEIHDLuz .taskText3{fill:#fff}#mermaid-svg-Xunb4T56sEIHDLuz .task0,#mermaid-svg-Xunb4T56sEIHDLuz .task1,#mermaid-svg-Xunb4T56sEIHDLuz .task2,#mermaid-svg-Xunb4T56sEIHDLuz .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-Xunb4T56sEIHDLuz .taskTextOutside0,#mermaid-svg-Xunb4T56sEIHDLuz .taskTextOutside2{fill:#000}#mermaid-svg-Xunb4T56sEIHDLuz .taskTextOutside1,#mermaid-svg-Xunb4T56sEIHDLuz .taskTextOutside3{fill:#000}#mermaid-svg-Xunb4T56sEIHDLuz .active0,#mermaid-svg-Xunb4T56sEIHDLuz .active1,#mermaid-svg-Xunb4T56sEIHDLuz .active2,#mermaid-svg-Xunb4T56sEIHDLuz .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-Xunb4T56sEIHDLuz .activeText0,#mermaid-svg-Xunb4T56sEIHDLuz .activeText1,#mermaid-svg-Xunb4T56sEIHDLuz .activeText2,#mermaid-svg-Xunb4T56sEIHDLuz .activeText3{fill:#000 !important}#mermaid-svg-Xunb4T56sEIHDLuz .done0,#mermaid-svg-Xunb4T56sEIHDLuz .done1,#mermaid-svg-Xunb4T56sEIHDLuz .done2,#mermaid-svg-Xunb4T56sEIHDLuz .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-Xunb4T56sEIHDLuz .doneText0,#mermaid-svg-Xunb4T56sEIHDLuz .doneText1,#mermaid-svg-Xunb4T56sEIHDLuz .doneText2,#mermaid-svg-Xunb4T56sEIHDLuz .doneText3{fill:#000 !important}#mermaid-svg-Xunb4T56sEIHDLuz .crit0,#mermaid-svg-Xunb4T56sEIHDLuz .crit1,#mermaid-svg-Xunb4T56sEIHDLuz .crit2,#mermaid-svg-Xunb4T56sEIHDLuz .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-Xunb4T56sEIHDLuz .activeCrit0,#mermaid-svg-Xunb4T56sEIHDLuz .activeCrit1,#mermaid-svg-Xunb4T56sEIHDLuz .activeCrit2,#mermaid-svg-Xunb4T56sEIHDLuz .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-Xunb4T56sEIHDLuz .doneCrit0,#mermaid-svg-Xunb4T56sEIHDLuz .doneCrit1,#mermaid-svg-Xunb4T56sEIHDLuz .doneCrit2,#mermaid-svg-Xunb4T56sEIHDLuz .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-Xunb4T56sEIHDLuz .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-Xunb4T56sEIHDLuz .milestoneText{font-style:italic}#mermaid-svg-Xunb4T56sEIHDLuz .doneCritText0,#mermaid-svg-Xunb4T56sEIHDLuz .doneCritText1,#mermaid-svg-Xunb4T56sEIHDLuz .doneCritText2,#mermaid-svg-Xunb4T56sEIHDLuz .doneCritText3{fill:#000 !important}#mermaid-svg-Xunb4T56sEIHDLuz .activeCritText0,#mermaid-svg-Xunb4T56sEIHDLuz .activeCritText1,#mermaid-svg-Xunb4T56sEIHDLuz .activeCritText2,#mermaid-svg-Xunb4T56sEIHDLuz .activeCritText3{fill:#000 !important}#mermaid-svg-Xunb4T56sEIHDLuz .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-Xunb4T56sEIHDLuz g.classGroup text .title{font-weight:bolder}#mermaid-svg-Xunb4T56sEIHDLuz g.clickable{cursor:pointer}#mermaid-svg-Xunb4T56sEIHDLuz g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-Xunb4T56sEIHDLuz g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-Xunb4T56sEIHDLuz .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-Xunb4T56sEIHDLuz .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-Xunb4T56sEIHDLuz .dashed-line{stroke-dasharray:3}#mermaid-svg-Xunb4T56sEIHDLuz #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz .commit-id,#mermaid-svg-Xunb4T56sEIHDLuz .commit-msg,#mermaid-svg-Xunb4T56sEIHDLuz .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-Xunb4T56sEIHDLuz g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-Xunb4T56sEIHDLuz g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-Xunb4T56sEIHDLuz g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-Xunb4T56sEIHDLuz .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-Xunb4T56sEIHDLuz .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-Xunb4T56sEIHDLuz .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-Xunb4T56sEIHDLuz .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-Xunb4T56sEIHDLuz .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-Xunb4T56sEIHDLuz .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-Xunb4T56sEIHDLuz .edgeLabel text{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Xunb4T56sEIHDLuz .node circle.state-start{fill:black;stroke:black}#mermaid-svg-Xunb4T56sEIHDLuz .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-Xunb4T56sEIHDLuz #statediagram-barbEnd{fill:#9370db}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-state .divider{stroke:#9370db}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-Xunb4T56sEIHDLuz .note-edge{stroke-dasharray:5}#mermaid-svg-Xunb4T56sEIHDLuz .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-Xunb4T56sEIHDLuz .error-icon{fill:#522}#mermaid-svg-Xunb4T56sEIHDLuz .error-text{fill:#522;stroke:#522}#mermaid-svg-Xunb4T56sEIHDLuz .edge-thickness-normal{stroke-width:2px}#mermaid-svg-Xunb4T56sEIHDLuz .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-Xunb4T56sEIHDLuz .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-Xunb4T56sEIHDLuz .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-Xunb4T56sEIHDLuz .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-Xunb4T56sEIHDLuz .marker{fill:#333}#mermaid-svg-Xunb4T56sEIHDLuz .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-Xunb4T56sEIHDLuz { color: rgba(0, 0, 0, 0.75); font: ; }</style>
1.發起認證
2.1持久化認證記錄
2.2 發起核驗請求
補償核驗結果
3. 變更核驗狀態
4.核驗成功
開始
認證系統
認證流水表
核驗狀態
核驗系統
定時任務
結束
  • 補償流程
<style>#mermaid-svg-t9qkfrcJ7lj2gnI4 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .label text{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .node rect,#mermaid-svg-t9qkfrcJ7lj2gnI4 .node circle,#mermaid-svg-t9qkfrcJ7lj2gnI4 .node ellipse,#mermaid-svg-t9qkfrcJ7lj2gnI4 .node polygon,#mermaid-svg-t9qkfrcJ7lj2gnI4 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .node .label{text-align:center;fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .node.clickable{cursor:pointer}#mermaid-svg-t9qkfrcJ7lj2gnI4 .arrowheadPath{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edgeLabel rect{opacity:0.9}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edgeLabel span{color:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .cluster text{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-t9qkfrcJ7lj2gnI4 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-t9qkfrcJ7lj2gnI4 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-t9qkfrcJ7lj2gnI4 .actor-line{stroke:grey}#mermaid-svg-t9qkfrcJ7lj2gnI4 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .sequenceNumber{fill:#fff}#mermaid-svg-t9qkfrcJ7lj2gnI4 #sequencenumber{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .messageText{fill:#333;stroke:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-t9qkfrcJ7lj2gnI4 .labelText,#mermaid-svg-t9qkfrcJ7lj2gnI4 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-t9qkfrcJ7lj2gnI4 .loopText,#mermaid-svg-t9qkfrcJ7lj2gnI4 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-t9qkfrcJ7lj2gnI4 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-t9qkfrcJ7lj2gnI4 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-t9qkfrcJ7lj2gnI4 .noteText,#mermaid-svg-t9qkfrcJ7lj2gnI4 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-t9qkfrcJ7lj2gnI4 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-t9qkfrcJ7lj2gnI4 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-t9qkfrcJ7lj2gnI4 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-t9qkfrcJ7lj2gnI4 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .section{stroke:none;opacity:0.2}#mermaid-svg-t9qkfrcJ7lj2gnI4 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .section2{fill:#fff400}#mermaid-svg-t9qkfrcJ7lj2gnI4 .section1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .section3{fill:#fff;opacity:0.2}#mermaid-svg-t9qkfrcJ7lj2gnI4 .sectionTitle0{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .sectionTitle1{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .sectionTitle2{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .sectionTitle3{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-t9qkfrcJ7lj2gnI4 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .grid path{stroke-width:0}#mermaid-svg-t9qkfrcJ7lj2gnI4 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .task{stroke-width:2}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskText:not([font-size]){font-size:11px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .task.clickable{cursor:pointer}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskText0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskText1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskText2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskText3{fill:#fff}#mermaid-svg-t9qkfrcJ7lj2gnI4 .task0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .task1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .task2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskTextOutside0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskTextOutside2{fill:#000}#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskTextOutside1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .taskTextOutside3{fill:#000}#mermaid-svg-t9qkfrcJ7lj2gnI4 .active0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .active1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .active2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeText0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeText1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeText2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeText3{fill:#000 !important}#mermaid-svg-t9qkfrcJ7lj2gnI4 .done0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .done1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .done2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneText0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneText1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneText2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneText3{fill:#000 !important}#mermaid-svg-t9qkfrcJ7lj2gnI4 .crit0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .crit1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .crit2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeCrit0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeCrit1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeCrit2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneCrit0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneCrit1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneCrit2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-t9qkfrcJ7lj2gnI4 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .milestoneText{font-style:italic}#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneCritText0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneCritText1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneCritText2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .doneCritText3{fill:#000 !important}#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeCritText0,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeCritText1,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeCritText2,#mermaid-svg-t9qkfrcJ7lj2gnI4 .activeCritText3{fill:#000 !important}#mermaid-svg-t9qkfrcJ7lj2gnI4 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.classGroup text .title{font-weight:bolder}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.clickable{cursor:pointer}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-t9qkfrcJ7lj2gnI4 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-t9qkfrcJ7lj2gnI4 .dashed-line{stroke-dasharray:3}#mermaid-svg-t9qkfrcJ7lj2gnI4 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 .commit-id,#mermaid-svg-t9qkfrcJ7lj2gnI4 .commit-msg,#mermaid-svg-t9qkfrcJ7lj2gnI4 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-t9qkfrcJ7lj2gnI4 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-t9qkfrcJ7lj2gnI4 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-t9qkfrcJ7lj2gnI4 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-t9qkfrcJ7lj2gnI4 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edgeLabel text{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-t9qkfrcJ7lj2gnI4 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-t9qkfrcJ7lj2gnI4 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-t9qkfrcJ7lj2gnI4 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-t9qkfrcJ7lj2gnI4 .note-edge{stroke-dasharray:5}#mermaid-svg-t9qkfrcJ7lj2gnI4 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-t9qkfrcJ7lj2gnI4 .error-icon{fill:#522}#mermaid-svg-t9qkfrcJ7lj2gnI4 .error-text{fill:#522;stroke:#522}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-t9qkfrcJ7lj2gnI4 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-t9qkfrcJ7lj2gnI4 .marker{fill:#333}#mermaid-svg-t9qkfrcJ7lj2gnI4 .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-t9qkfrcJ7lj2gnI4 { color: rgba(0, 0, 0, 0.75); font: ; }</style>
1.輪詢認證流水
2.補償查詢核驗狀態
3. 回傳核驗結果
4.變更認證流水及核驗狀態
定時任務
營銷系統
核驗系統
認證流水表
核驗狀態
結束

場景Q&A

  • Q:本地事務認證流水成功了,外部核驗系統提交失敗了怎么辦?

    A:通過定時任務補償觸發二次提交,只要外部事物提交一直處于未成功,便一直會被重試提交,直到成功

  • Q:外部核驗系統事務完成了,本地事務認證流水提前被作廢了怎么辦?

    A:以本地事務認證流水的結果為準,本地事務是通過定時任務進行補充提交+外部事務狀態核驗查詢的,即時在臨界點外部事務完成了,但是超過了業務處理時間已經關閉,不會再補充修改,這也是根據業務場景做的取舍,用戶可以再次發起新流程進行核驗

1.2 本地事務表 + 事務訊息

互動流程

在這里插入圖片描述

  • prepare 準備階段 本地客戶端向DB、MQ發送prepare請求
  • ack 準備確認階段 DB、MQ作為事務參與者回傳本地客戶端ack確認
  • commit/rollback 提交/回滾階段 根據事務參與者在準備確認階段回傳結果進行事務提交或回滾,此時一旦有事務參與者回傳例外或超時未回傳則進行回滾提交
  • callback 補償回呼階段 當事務超時提交時,則由MQ進行回呼查詢資料庫本地事務情況
  • commit/rollback 提交/回滾階段 根據補償回呼階段進行事務提交和回滾,實作分布式事務的最終一致性

場景:分庫分表路由欄位系結

在這里插入圖片描述

專案背景

該業務是在分庫分表場景下,需要一個切分鍵欄位進行資料分片路由,一般我們ToC業務的話會使用userId這樣的欄位進行切分,然而水平切分資料帶來了資料庫讀寫性能的同時也存在一個問題,那就是查詢必須攜帶切分鍵才可以完成,因為要依賴它進行資料路由查詢,比如在以userId進行資料路由切分時,如果想按照用戶的身份證、姓名等進行匹配查詢是無法實作的,因為我們事先是不知道userId、身份證、姓名的等值匹配關系,一般而言,我們可以通過HBase + ES的方案進行解決,即監聽不同庫的binlog日志,將其按照時間進行排序切分匯入HBase表中,加入要檢索的索引到ES中解決分庫分表下資料切片產生的聚合問題,

分布式事務

基于以上場景,除了通過HBase+ES實作之外,還可以通過切分鍵與非切分鍵進行資料系結解決,但是由于切分鍵與非切分鍵的路由一般不一致,資料會分散到不同庫,因此無法做本地事務,這是我們需要解決的分布式事務問題,

設計方案

欄位處理方式路由鍵存盤格式
切分鍵DB同步寫,按照切分鍵路由切分鍵<切分鍵,非切分鍵A,非切分鍵B,非切分鍵C>
非切分鍵MQ異步寫,按照非切分鍵路由冗余存盤,保存與切分鍵資料關系非切分鍵<非切分鍵A,切分鍵>
<非切分鍵B,切分鍵>
<非切分鍵C,切分鍵>
  • 互動流程
<style>#mermaid-svg-2fcIb9H1Dp5GGE7K .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .label text{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .node rect,#mermaid-svg-2fcIb9H1Dp5GGE7K .node circle,#mermaid-svg-2fcIb9H1Dp5GGE7K .node ellipse,#mermaid-svg-2fcIb9H1Dp5GGE7K .node polygon,#mermaid-svg-2fcIb9H1Dp5GGE7K .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-2fcIb9H1Dp5GGE7K .node .label{text-align:center;fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .node.clickable{cursor:pointer}#mermaid-svg-2fcIb9H1Dp5GGE7K .arrowheadPath{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-2fcIb9H1Dp5GGE7K .flowchart-link{stroke:#333;fill:none}#mermaid-svg-2fcIb9H1Dp5GGE7K .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-2fcIb9H1Dp5GGE7K .edgeLabel rect{opacity:0.9}#mermaid-svg-2fcIb9H1Dp5GGE7K .edgeLabel span{color:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-2fcIb9H1Dp5GGE7K .cluster text{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-2fcIb9H1Dp5GGE7K .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-2fcIb9H1Dp5GGE7K text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-2fcIb9H1Dp5GGE7K .actor-line{stroke:grey}#mermaid-svg-2fcIb9H1Dp5GGE7K .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .sequenceNumber{fill:#fff}#mermaid-svg-2fcIb9H1Dp5GGE7K #sequencenumber{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K #crosshead path{fill:#333;stroke:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .messageText{fill:#333;stroke:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-2fcIb9H1Dp5GGE7K .labelText,#mermaid-svg-2fcIb9H1Dp5GGE7K .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-2fcIb9H1Dp5GGE7K .loopText,#mermaid-svg-2fcIb9H1Dp5GGE7K .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-2fcIb9H1Dp5GGE7K .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-2fcIb9H1Dp5GGE7K .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-2fcIb9H1Dp5GGE7K .noteText,#mermaid-svg-2fcIb9H1Dp5GGE7K .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-2fcIb9H1Dp5GGE7K .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-2fcIb9H1Dp5GGE7K .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-2fcIb9H1Dp5GGE7K .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-2fcIb9H1Dp5GGE7K .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K .section{stroke:none;opacity:0.2}#mermaid-svg-2fcIb9H1Dp5GGE7K .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-2fcIb9H1Dp5GGE7K .section2{fill:#fff400}#mermaid-svg-2fcIb9H1Dp5GGE7K .section1,#mermaid-svg-2fcIb9H1Dp5GGE7K .section3{fill:#fff;opacity:0.2}#mermaid-svg-2fcIb9H1Dp5GGE7K .sectionTitle0{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .sectionTitle1{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .sectionTitle2{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .sectionTitle3{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-2fcIb9H1Dp5GGE7K .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K .grid path{stroke-width:0}#mermaid-svg-2fcIb9H1Dp5GGE7K .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-2fcIb9H1Dp5GGE7K .task{stroke-width:2}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskText:not([font-size]){font-size:11px}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-2fcIb9H1Dp5GGE7K .task.clickable{cursor:pointer}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskText0,#mermaid-svg-2fcIb9H1Dp5GGE7K .taskText1,#mermaid-svg-2fcIb9H1Dp5GGE7K .taskText2,#mermaid-svg-2fcIb9H1Dp5GGE7K .taskText3{fill:#fff}#mermaid-svg-2fcIb9H1Dp5GGE7K .task0,#mermaid-svg-2fcIb9H1Dp5GGE7K .task1,#mermaid-svg-2fcIb9H1Dp5GGE7K .task2,#mermaid-svg-2fcIb9H1Dp5GGE7K .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskTextOutside0,#mermaid-svg-2fcIb9H1Dp5GGE7K .taskTextOutside2{fill:#000}#mermaid-svg-2fcIb9H1Dp5GGE7K .taskTextOutside1,#mermaid-svg-2fcIb9H1Dp5GGE7K .taskTextOutside3{fill:#000}#mermaid-svg-2fcIb9H1Dp5GGE7K .active0,#mermaid-svg-2fcIb9H1Dp5GGE7K .active1,#mermaid-svg-2fcIb9H1Dp5GGE7K .active2,#mermaid-svg-2fcIb9H1Dp5GGE7K .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-2fcIb9H1Dp5GGE7K .activeText0,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeText1,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeText2,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeText3{fill:#000 !important}#mermaid-svg-2fcIb9H1Dp5GGE7K .done0,#mermaid-svg-2fcIb9H1Dp5GGE7K .done1,#mermaid-svg-2fcIb9H1Dp5GGE7K .done2,#mermaid-svg-2fcIb9H1Dp5GGE7K .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-2fcIb9H1Dp5GGE7K .doneText0,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneText1,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneText2,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneText3{fill:#000 !important}#mermaid-svg-2fcIb9H1Dp5GGE7K .crit0,#mermaid-svg-2fcIb9H1Dp5GGE7K .crit1,#mermaid-svg-2fcIb9H1Dp5GGE7K .crit2,#mermaid-svg-2fcIb9H1Dp5GGE7K .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-2fcIb9H1Dp5GGE7K .activeCrit0,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeCrit1,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeCrit2,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-2fcIb9H1Dp5GGE7K .doneCrit0,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneCrit1,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneCrit2,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-2fcIb9H1Dp5GGE7K .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-2fcIb9H1Dp5GGE7K .milestoneText{font-style:italic}#mermaid-svg-2fcIb9H1Dp5GGE7K .doneCritText0,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneCritText1,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneCritText2,#mermaid-svg-2fcIb9H1Dp5GGE7K .doneCritText3{fill:#000 !important}#mermaid-svg-2fcIb9H1Dp5GGE7K .activeCritText0,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeCritText1,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeCritText2,#mermaid-svg-2fcIb9H1Dp5GGE7K .activeCritText3{fill:#000 !important}#mermaid-svg-2fcIb9H1Dp5GGE7K .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-2fcIb9H1Dp5GGE7K g.classGroup text .title{font-weight:bolder}#mermaid-svg-2fcIb9H1Dp5GGE7K g.clickable{cursor:pointer}#mermaid-svg-2fcIb9H1Dp5GGE7K g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-2fcIb9H1Dp5GGE7K g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-2fcIb9H1Dp5GGE7K .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-2fcIb9H1Dp5GGE7K .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-2fcIb9H1Dp5GGE7K .dashed-line{stroke-dasharray:3}#mermaid-svg-2fcIb9H1Dp5GGE7K #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K .commit-id,#mermaid-svg-2fcIb9H1Dp5GGE7K .commit-msg,#mermaid-svg-2fcIb9H1Dp5GGE7K .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-2fcIb9H1Dp5GGE7K g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-2fcIb9H1Dp5GGE7K g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-2fcIb9H1Dp5GGE7K g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-2fcIb9H1Dp5GGE7K .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-2fcIb9H1Dp5GGE7K .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-2fcIb9H1Dp5GGE7K .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-2fcIb9H1Dp5GGE7K .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-2fcIb9H1Dp5GGE7K .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-2fcIb9H1Dp5GGE7K .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-2fcIb9H1Dp5GGE7K .edgeLabel text{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-2fcIb9H1Dp5GGE7K .node circle.state-start{fill:black;stroke:black}#mermaid-svg-2fcIb9H1Dp5GGE7K .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-2fcIb9H1Dp5GGE7K #statediagram-barbEnd{fill:#9370db}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-state .divider{stroke:#9370db}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-2fcIb9H1Dp5GGE7K .note-edge{stroke-dasharray:5}#mermaid-svg-2fcIb9H1Dp5GGE7K .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-2fcIb9H1Dp5GGE7K .error-icon{fill:#522}#mermaid-svg-2fcIb9H1Dp5GGE7K .error-text{fill:#522;stroke:#522}#mermaid-svg-2fcIb9H1Dp5GGE7K .edge-thickness-normal{stroke-width:2px}#mermaid-svg-2fcIb9H1Dp5GGE7K .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-2fcIb9H1Dp5GGE7K .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-2fcIb9H1Dp5GGE7K .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-2fcIb9H1Dp5GGE7K .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-2fcIb9H1Dp5GGE7K .marker{fill:#333}#mermaid-svg-2fcIb9H1Dp5GGE7K .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-2fcIb9H1Dp5GGE7K { color: rgba(0, 0, 0, 0.75); font: ; }</style>
切分鍵資料同步寫
ack
非切分鍵資料異步寫
ack
commit
ack
commit
ack
超時回呼查詢本地事務狀態
成功
失敗
cancel
cancel
階段
prepare
DB
prepare結果
MQ
階段
commit
DB
commit結果
MQ
結束
階段
Cancel
DB
MQ

場景Q&A

  • Q:異步MQ寫有延遲,查不到切分鍵如何處理?

    A:事務處理開始階段通過Redis記錄事務開啟的分布式鎖標識,當其他存在沖突的同業務在該事務的處理程序有查詢時,通過判斷分布式鎖標識是否存在來判斷事務的開啟,若存在則異步等待并發起間隔查詢直到事務超時,若事務超時周期內反復查詢到則回傳,否則根據事務處理后結果回傳

  • Q:本地事務與MQ事務是如何協作的?

    A:相當于兩個2PC事務協作,

    • 1.一階段DB、MQ同時prepare(并行)
    • 2.二階段DB先commit,成功后MQ再commit(串行)
    流程階段操作Ack反饋持久化是否結束分布式事務成功
    正向流程PrepareDB prepare
    MQ prepare
    YesNoNoNo
    正向流程CommitDB commit
    MQ commit
    YesYesYesYes
    ------
    例外流程PrepareDB 或 MQ 例外NoNoYesNo
    例外流程CommitDB提交例外NoNoYesNo
    例外流程CommitMQ提交超時
    回呼本地事務狀態,本地事務成功則提交MQ事務
    YesYesYesYes
    例外流程CommitMQ提交超時
    回呼本地事務狀態,本地事務失敗則取消MQ事務
    YesNoYesNo
  • Q:會不會存在MQ事務成功,本地事務失敗?

    A:不會,而且要避免這種情況發生,兩個2PC事務的prepare準備階段可以同時發起,但在commit提交階段要先保證本地資料庫事務成功之后再進行MQ事務訊息的commit,也就是在commit階段是存在依賴關系、串行化之行的

  • Q:事務訊息如何確保最終一致?

    A:prepare階段失敗、本地事務commit階段則均不會持久化;當prepare階段成功、本地事務commit成功,此時MQ的commit階段例外,則依賴MQ事務訊息的超時commit機制觸發回呼本地事務狀態介面方法來決定MQ的二階段是commit還是cancel

1.3 TCC(Try-Commit-Cancel)

互動流程

在這里插入圖片描述
TCC事務其實主要包含兩個階段:Try階段、Confirm/Cancel階段,

  • try-嘗試執行業務
    完成所有業務檢查(一致性)
    預留必須業務資源(準隔離性)
  • confirm-確認執行業務
    真正執行業務
    不作任何業務檢查
    只使用Try階段預留的業務資源
    Confirm操作必須保證冪等性
  • cancel-取消執行業務
    釋放Try階段預留的業務資源
    Cancel操作必須保證冪等性

從TCC的邏輯模型上我們可以看到,TCC的核心思想是,Try階段檢查并預留資源,確保在Confirm階段有資源可用,這樣可以最大程度的確保Confirm階段能夠執行成功,這里的資源可以是DB,或者MQRPC,只要是分布式環境中的事務載體就可以,而且需要這些分布式事務的參與者具備正逆向條件,比如DB、MQ的事務可以支持2PC,可以根據協調者對其進行事務提交或者取消操作,RPC比如賬戶服務可以支持正向增加也可以支持逆向減少,除此之外,DB、MQ要自身支持事務的ACID,這是參與分布式事務的原子性保證,RPC底層也是DB,這里可以等同理解,以上參與者具備參與分布式事務的基本條件后便可以進行整合和使用,業務流程的驅動和事務的完整性由中間協調者來操作和推進,

場景:積分商品兌換

在這里插入圖片描述

專案背景

這是一個電商系統比較經典的下單、扣款、發貨流程,在下單之前會通過一系列商品在架狀態、庫存數量、購買限制等有效性過濾,然后在業務系統中進行一個商品兌換的場景,

分布式事務

由于是商品兌換,對于用戶和系統本身來說是這個程序一個原子性的、一鍵完成的操作,因此下單+動賬+發貨是一個現實存在的分布式事務,這里假設訂單資料和動賬資料在一個本地資料庫事務中,持久化開啟資料庫本地事務,該事務中記錄訂單生成資料動賬資料資訊,以及發貨狀態的資訊記錄,這里需要解決的分布式事務是訂單資料、動賬資料、發貨狀態三種的最終一致

設計方案

資料系統事務正向流程逆向流程
訂單資料本地系統本地事務本地事務2PC保證定時任務,例外關單
動賬資料本地系統本地事務本地事務2PC保證定時任務,逆向補賬
發貨狀態外部系統分布式事務聯同本地事務提交 / 定時任務補償提交定時任務,驅動發歡訓取消
  • 正向流程
<style>#mermaid-svg-wlCq1NeTfrRIl2a0 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .label text{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .node rect,#mermaid-svg-wlCq1NeTfrRIl2a0 .node circle,#mermaid-svg-wlCq1NeTfrRIl2a0 .node ellipse,#mermaid-svg-wlCq1NeTfrRIl2a0 .node polygon,#mermaid-svg-wlCq1NeTfrRIl2a0 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-wlCq1NeTfrRIl2a0 .node .label{text-align:center;fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .node.clickable{cursor:pointer}#mermaid-svg-wlCq1NeTfrRIl2a0 .arrowheadPath{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-wlCq1NeTfrRIl2a0 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-wlCq1NeTfrRIl2a0 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-wlCq1NeTfrRIl2a0 .edgeLabel rect{opacity:0.9}#mermaid-svg-wlCq1NeTfrRIl2a0 .edgeLabel span{color:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-wlCq1NeTfrRIl2a0 .cluster text{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-wlCq1NeTfrRIl2a0 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-wlCq1NeTfrRIl2a0 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-wlCq1NeTfrRIl2a0 .actor-line{stroke:grey}#mermaid-svg-wlCq1NeTfrRIl2a0 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .sequenceNumber{fill:#fff}#mermaid-svg-wlCq1NeTfrRIl2a0 #sequencenumber{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .messageText{fill:#333;stroke:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-wlCq1NeTfrRIl2a0 .labelText,#mermaid-svg-wlCq1NeTfrRIl2a0 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-wlCq1NeTfrRIl2a0 .loopText,#mermaid-svg-wlCq1NeTfrRIl2a0 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-wlCq1NeTfrRIl2a0 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-wlCq1NeTfrRIl2a0 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-wlCq1NeTfrRIl2a0 .noteText,#mermaid-svg-wlCq1NeTfrRIl2a0 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-wlCq1NeTfrRIl2a0 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-wlCq1NeTfrRIl2a0 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-wlCq1NeTfrRIl2a0 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-wlCq1NeTfrRIl2a0 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 .section{stroke:none;opacity:0.2}#mermaid-svg-wlCq1NeTfrRIl2a0 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-wlCq1NeTfrRIl2a0 .section2{fill:#fff400}#mermaid-svg-wlCq1NeTfrRIl2a0 .section1,#mermaid-svg-wlCq1NeTfrRIl2a0 .section3{fill:#fff;opacity:0.2}#mermaid-svg-wlCq1NeTfrRIl2a0 .sectionTitle0{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .sectionTitle1{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .sectionTitle2{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .sectionTitle3{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-wlCq1NeTfrRIl2a0 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 .grid path{stroke-width:0}#mermaid-svg-wlCq1NeTfrRIl2a0 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-wlCq1NeTfrRIl2a0 .task{stroke-width:2}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskText:not([font-size]){font-size:11px}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-wlCq1NeTfrRIl2a0 .task.clickable{cursor:pointer}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskText0,#mermaid-svg-wlCq1NeTfrRIl2a0 .taskText1,#mermaid-svg-wlCq1NeTfrRIl2a0 .taskText2,#mermaid-svg-wlCq1NeTfrRIl2a0 .taskText3{fill:#fff}#mermaid-svg-wlCq1NeTfrRIl2a0 .task0,#mermaid-svg-wlCq1NeTfrRIl2a0 .task1,#mermaid-svg-wlCq1NeTfrRIl2a0 .task2,#mermaid-svg-wlCq1NeTfrRIl2a0 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskTextOutside0,#mermaid-svg-wlCq1NeTfrRIl2a0 .taskTextOutside2{fill:#000}#mermaid-svg-wlCq1NeTfrRIl2a0 .taskTextOutside1,#mermaid-svg-wlCq1NeTfrRIl2a0 .taskTextOutside3{fill:#000}#mermaid-svg-wlCq1NeTfrRIl2a0 .active0,#mermaid-svg-wlCq1NeTfrRIl2a0 .active1,#mermaid-svg-wlCq1NeTfrRIl2a0 .active2,#mermaid-svg-wlCq1NeTfrRIl2a0 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-wlCq1NeTfrRIl2a0 .activeText0,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeText1,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeText2,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeText3{fill:#000 !important}#mermaid-svg-wlCq1NeTfrRIl2a0 .done0,#mermaid-svg-wlCq1NeTfrRIl2a0 .done1,#mermaid-svg-wlCq1NeTfrRIl2a0 .done2,#mermaid-svg-wlCq1NeTfrRIl2a0 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-wlCq1NeTfrRIl2a0 .doneText0,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneText1,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneText2,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneText3{fill:#000 !important}#mermaid-svg-wlCq1NeTfrRIl2a0 .crit0,#mermaid-svg-wlCq1NeTfrRIl2a0 .crit1,#mermaid-svg-wlCq1NeTfrRIl2a0 .crit2,#mermaid-svg-wlCq1NeTfrRIl2a0 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-wlCq1NeTfrRIl2a0 .activeCrit0,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeCrit1,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeCrit2,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-wlCq1NeTfrRIl2a0 .doneCrit0,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneCrit1,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneCrit2,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-wlCq1NeTfrRIl2a0 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-wlCq1NeTfrRIl2a0 .milestoneText{font-style:italic}#mermaid-svg-wlCq1NeTfrRIl2a0 .doneCritText0,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneCritText1,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneCritText2,#mermaid-svg-wlCq1NeTfrRIl2a0 .doneCritText3{fill:#000 !important}#mermaid-svg-wlCq1NeTfrRIl2a0 .activeCritText0,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeCritText1,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeCritText2,#mermaid-svg-wlCq1NeTfrRIl2a0 .activeCritText3{fill:#000 !important}#mermaid-svg-wlCq1NeTfrRIl2a0 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-wlCq1NeTfrRIl2a0 g.classGroup text .title{font-weight:bolder}#mermaid-svg-wlCq1NeTfrRIl2a0 g.clickable{cursor:pointer}#mermaid-svg-wlCq1NeTfrRIl2a0 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-wlCq1NeTfrRIl2a0 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-wlCq1NeTfrRIl2a0 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-wlCq1NeTfrRIl2a0 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-wlCq1NeTfrRIl2a0 .dashed-line{stroke-dasharray:3}#mermaid-svg-wlCq1NeTfrRIl2a0 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 .commit-id,#mermaid-svg-wlCq1NeTfrRIl2a0 .commit-msg,#mermaid-svg-wlCq1NeTfrRIl2a0 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-wlCq1NeTfrRIl2a0 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-wlCq1NeTfrRIl2a0 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-wlCq1NeTfrRIl2a0 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-wlCq1NeTfrRIl2a0 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-wlCq1NeTfrRIl2a0 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-wlCq1NeTfrRIl2a0 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-wlCq1NeTfrRIl2a0 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-wlCq1NeTfrRIl2a0 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-wlCq1NeTfrRIl2a0 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-wlCq1NeTfrRIl2a0 .edgeLabel text{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-wlCq1NeTfrRIl2a0 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-wlCq1NeTfrRIl2a0 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-wlCq1NeTfrRIl2a0 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-wlCq1NeTfrRIl2a0 .note-edge{stroke-dasharray:5}#mermaid-svg-wlCq1NeTfrRIl2a0 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-wlCq1NeTfrRIl2a0 .error-icon{fill:#522}#mermaid-svg-wlCq1NeTfrRIl2a0 .error-text{fill:#522;stroke:#522}#mermaid-svg-wlCq1NeTfrRIl2a0 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-wlCq1NeTfrRIl2a0 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-wlCq1NeTfrRIl2a0 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-wlCq1NeTfrRIl2a0 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-wlCq1NeTfrRIl2a0 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-wlCq1NeTfrRIl2a0 .marker{fill:#333}#mermaid-svg-wlCq1NeTfrRIl2a0 .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-wlCq1NeTfrRIl2a0 { color: rgba(0, 0, 0, 0.75); font: ; }</style>
1.商品兌換
2.下單&動賬
3. 呼叫發貨
4. 變更發貨狀態
補償輪詢訂單
5. 發貨成功
開始
營銷系統
賬戶表
訂單表
發貨狀態
發貨系統
定時任務
結束
  • 補償流程
<style>#mermaid-svg-lrsFtSQcl0zSUQoK .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .label text{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .node rect,#mermaid-svg-lrsFtSQcl0zSUQoK .node circle,#mermaid-svg-lrsFtSQcl0zSUQoK .node ellipse,#mermaid-svg-lrsFtSQcl0zSUQoK .node polygon,#mermaid-svg-lrsFtSQcl0zSUQoK .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-lrsFtSQcl0zSUQoK .node .label{text-align:center;fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .node.clickable{cursor:pointer}#mermaid-svg-lrsFtSQcl0zSUQoK .arrowheadPath{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-lrsFtSQcl0zSUQoK .flowchart-link{stroke:#333;fill:none}#mermaid-svg-lrsFtSQcl0zSUQoK .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-lrsFtSQcl0zSUQoK .edgeLabel rect{opacity:0.9}#mermaid-svg-lrsFtSQcl0zSUQoK .edgeLabel span{color:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-lrsFtSQcl0zSUQoK .cluster text{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-lrsFtSQcl0zSUQoK .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-lrsFtSQcl0zSUQoK text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-lrsFtSQcl0zSUQoK .actor-line{stroke:grey}#mermaid-svg-lrsFtSQcl0zSUQoK .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-lrsFtSQcl0zSUQoK #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .sequenceNumber{fill:#fff}#mermaid-svg-lrsFtSQcl0zSUQoK #sequencenumber{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK #crosshead path{fill:#333;stroke:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .messageText{fill:#333;stroke:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-lrsFtSQcl0zSUQoK .labelText,#mermaid-svg-lrsFtSQcl0zSUQoK .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-lrsFtSQcl0zSUQoK .loopText,#mermaid-svg-lrsFtSQcl0zSUQoK .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-lrsFtSQcl0zSUQoK .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-lrsFtSQcl0zSUQoK .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-lrsFtSQcl0zSUQoK .noteText,#mermaid-svg-lrsFtSQcl0zSUQoK .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-lrsFtSQcl0zSUQoK .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-lrsFtSQcl0zSUQoK .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-lrsFtSQcl0zSUQoK .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-lrsFtSQcl0zSUQoK .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK .section{stroke:none;opacity:0.2}#mermaid-svg-lrsFtSQcl0zSUQoK .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-lrsFtSQcl0zSUQoK .section2{fill:#fff400}#mermaid-svg-lrsFtSQcl0zSUQoK .section1,#mermaid-svg-lrsFtSQcl0zSUQoK .section3{fill:#fff;opacity:0.2}#mermaid-svg-lrsFtSQcl0zSUQoK .sectionTitle0{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .sectionTitle1{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .sectionTitle2{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .sectionTitle3{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-lrsFtSQcl0zSUQoK .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK .grid path{stroke-width:0}#mermaid-svg-lrsFtSQcl0zSUQoK .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-lrsFtSQcl0zSUQoK .task{stroke-width:2}#mermaid-svg-lrsFtSQcl0zSUQoK .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK .taskText:not([font-size]){font-size:11px}#mermaid-svg-lrsFtSQcl0zSUQoK .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-lrsFtSQcl0zSUQoK .task.clickable{cursor:pointer}#mermaid-svg-lrsFtSQcl0zSUQoK .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-lrsFtSQcl0zSUQoK .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-lrsFtSQcl0zSUQoK .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-lrsFtSQcl0zSUQoK .taskText0,#mermaid-svg-lrsFtSQcl0zSUQoK .taskText1,#mermaid-svg-lrsFtSQcl0zSUQoK .taskText2,#mermaid-svg-lrsFtSQcl0zSUQoK .taskText3{fill:#fff}#mermaid-svg-lrsFtSQcl0zSUQoK .task0,#mermaid-svg-lrsFtSQcl0zSUQoK .task1,#mermaid-svg-lrsFtSQcl0zSUQoK .task2,#mermaid-svg-lrsFtSQcl0zSUQoK .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-lrsFtSQcl0zSUQoK .taskTextOutside0,#mermaid-svg-lrsFtSQcl0zSUQoK .taskTextOutside2{fill:#000}#mermaid-svg-lrsFtSQcl0zSUQoK .taskTextOutside1,#mermaid-svg-lrsFtSQcl0zSUQoK .taskTextOutside3{fill:#000}#mermaid-svg-lrsFtSQcl0zSUQoK .active0,#mermaid-svg-lrsFtSQcl0zSUQoK .active1,#mermaid-svg-lrsFtSQcl0zSUQoK .active2,#mermaid-svg-lrsFtSQcl0zSUQoK .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-lrsFtSQcl0zSUQoK .activeText0,#mermaid-svg-lrsFtSQcl0zSUQoK .activeText1,#mermaid-svg-lrsFtSQcl0zSUQoK .activeText2,#mermaid-svg-lrsFtSQcl0zSUQoK .activeText3{fill:#000 !important}#mermaid-svg-lrsFtSQcl0zSUQoK .done0,#mermaid-svg-lrsFtSQcl0zSUQoK .done1,#mermaid-svg-lrsFtSQcl0zSUQoK .done2,#mermaid-svg-lrsFtSQcl0zSUQoK .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-lrsFtSQcl0zSUQoK .doneText0,#mermaid-svg-lrsFtSQcl0zSUQoK .doneText1,#mermaid-svg-lrsFtSQcl0zSUQoK .doneText2,#mermaid-svg-lrsFtSQcl0zSUQoK .doneText3{fill:#000 !important}#mermaid-svg-lrsFtSQcl0zSUQoK .crit0,#mermaid-svg-lrsFtSQcl0zSUQoK .crit1,#mermaid-svg-lrsFtSQcl0zSUQoK .crit2,#mermaid-svg-lrsFtSQcl0zSUQoK .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-lrsFtSQcl0zSUQoK .activeCrit0,#mermaid-svg-lrsFtSQcl0zSUQoK .activeCrit1,#mermaid-svg-lrsFtSQcl0zSUQoK .activeCrit2,#mermaid-svg-lrsFtSQcl0zSUQoK .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-lrsFtSQcl0zSUQoK .doneCrit0,#mermaid-svg-lrsFtSQcl0zSUQoK .doneCrit1,#mermaid-svg-lrsFtSQcl0zSUQoK .doneCrit2,#mermaid-svg-lrsFtSQcl0zSUQoK .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-lrsFtSQcl0zSUQoK .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-lrsFtSQcl0zSUQoK .milestoneText{font-style:italic}#mermaid-svg-lrsFtSQcl0zSUQoK .doneCritText0,#mermaid-svg-lrsFtSQcl0zSUQoK .doneCritText1,#mermaid-svg-lrsFtSQcl0zSUQoK .doneCritText2,#mermaid-svg-lrsFtSQcl0zSUQoK .doneCritText3{fill:#000 !important}#mermaid-svg-lrsFtSQcl0zSUQoK .activeCritText0,#mermaid-svg-lrsFtSQcl0zSUQoK .activeCritText1,#mermaid-svg-lrsFtSQcl0zSUQoK .activeCritText2,#mermaid-svg-lrsFtSQcl0zSUQoK .activeCritText3{fill:#000 !important}#mermaid-svg-lrsFtSQcl0zSUQoK .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-lrsFtSQcl0zSUQoK g.classGroup text .title{font-weight:bolder}#mermaid-svg-lrsFtSQcl0zSUQoK g.clickable{cursor:pointer}#mermaid-svg-lrsFtSQcl0zSUQoK g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-lrsFtSQcl0zSUQoK g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-lrsFtSQcl0zSUQoK .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-lrsFtSQcl0zSUQoK .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-lrsFtSQcl0zSUQoK .dashed-line{stroke-dasharray:3}#mermaid-svg-lrsFtSQcl0zSUQoK #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK .commit-id,#mermaid-svg-lrsFtSQcl0zSUQoK .commit-msg,#mermaid-svg-lrsFtSQcl0zSUQoK .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-lrsFtSQcl0zSUQoK g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-lrsFtSQcl0zSUQoK g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-lrsFtSQcl0zSUQoK g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-lrsFtSQcl0zSUQoK .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-lrsFtSQcl0zSUQoK .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-lrsFtSQcl0zSUQoK .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-lrsFtSQcl0zSUQoK .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-lrsFtSQcl0zSUQoK .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-lrsFtSQcl0zSUQoK .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-lrsFtSQcl0zSUQoK .edgeLabel text{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-lrsFtSQcl0zSUQoK .node circle.state-start{fill:black;stroke:black}#mermaid-svg-lrsFtSQcl0zSUQoK .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-lrsFtSQcl0zSUQoK #statediagram-barbEnd{fill:#9370db}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-state .divider{stroke:#9370db}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-lrsFtSQcl0zSUQoK .note-edge{stroke-dasharray:5}#mermaid-svg-lrsFtSQcl0zSUQoK .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-lrsFtSQcl0zSUQoK .error-icon{fill:#522}#mermaid-svg-lrsFtSQcl0zSUQoK .error-text{fill:#522;stroke:#522}#mermaid-svg-lrsFtSQcl0zSUQoK .edge-thickness-normal{stroke-width:2px}#mermaid-svg-lrsFtSQcl0zSUQoK .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-lrsFtSQcl0zSUQoK .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-lrsFtSQcl0zSUQoK .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-lrsFtSQcl0zSUQoK .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-lrsFtSQcl0zSUQoK .marker{fill:#333}#mermaid-svg-lrsFtSQcl0zSUQoK .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-lrsFtSQcl0zSUQoK { color: rgba(0, 0, 0, 0.75); font: ; }</style>
1.輪詢訂單
2.補償發貨
3.1 標記發貨成功
3.2 回滾賬戶&關閉訂單&標記發貨終止
定時任務
營銷系統
發貨系統
發貨狀態
發貨成功
賬戶表
訂單表
發貨狀態
發貨失敗
結束

場景Q&A

  • Q:動賬扣款成功,但是發貨失敗怎么辦?

    A: 定時任務根據發貨狀態進行發貨流程驅動

    • 定時任務補償再次發貨
      發貨成功則分布式事務最終一致,下游發貨系統進行發貨防重處理
    • 發貨失敗進入逆向流程
      定時任務驅動發貨最終一致理論上可以一直進行,但是發貨可能有一個流程時效和庫存售罄的問題,可以根據業務場景進行配置比如2天內重復呼叫失敗或呼叫回傳無庫存則進入逆向關單退款流程使得分布式事務恢復成最開始的一致性狀態
  • Q:逆向流程回滾賬戶扣款,怎么防重?

    A:賬戶流水表做唯一索引正逆向型別 + 業務ID,和賬戶額度表進行本地事務操作,確保只能成功一筆正向/逆向業務操作

場景:廣告任務結算

在這里插入圖片描述

專案背景

當一個App有了足夠多的用戶體量,便開始有商家進行廣告或商品的投放,平臺通過包裝運營活動、廣告位等,將用戶曝光與商家付費結合達到流量變現的目的,

分布式事務

當用戶進行瀏覽、關注、商品購買、視頻觀看、App下載等多種任務,我們會根據商家配置等付費規則進行商家廣告費用的扣減,同時還要為用戶完成任務進行獎勵結算,此時的分布式事務便是商家賬戶扣減與用戶賬戶增加的資料一致性問題

設計方案

角色資料系統操作
平臺業務流水結算系統扣減商戶費用、增加用戶余額
商戶商戶余額商戶系統扣減費用
用戶用戶余額用戶系統增加余額
  • 互動流程
<style>#mermaid-svg-bqnrbsisyc9Ih9xg .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .label text{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .node rect,#mermaid-svg-bqnrbsisyc9Ih9xg .node circle,#mermaid-svg-bqnrbsisyc9Ih9xg .node ellipse,#mermaid-svg-bqnrbsisyc9Ih9xg .node polygon,#mermaid-svg-bqnrbsisyc9Ih9xg .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-bqnrbsisyc9Ih9xg .node .label{text-align:center;fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .node.clickable{cursor:pointer}#mermaid-svg-bqnrbsisyc9Ih9xg .arrowheadPath{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-bqnrbsisyc9Ih9xg .flowchart-link{stroke:#333;fill:none}#mermaid-svg-bqnrbsisyc9Ih9xg .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-bqnrbsisyc9Ih9xg .edgeLabel rect{opacity:0.9}#mermaid-svg-bqnrbsisyc9Ih9xg .edgeLabel span{color:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-bqnrbsisyc9Ih9xg .cluster text{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-bqnrbsisyc9Ih9xg .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-bqnrbsisyc9Ih9xg text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-bqnrbsisyc9Ih9xg .actor-line{stroke:grey}#mermaid-svg-bqnrbsisyc9Ih9xg .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-bqnrbsisyc9Ih9xg #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .sequenceNumber{fill:#fff}#mermaid-svg-bqnrbsisyc9Ih9xg #sequencenumber{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg #crosshead path{fill:#333;stroke:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .messageText{fill:#333;stroke:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-bqnrbsisyc9Ih9xg .labelText,#mermaid-svg-bqnrbsisyc9Ih9xg .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-bqnrbsisyc9Ih9xg .loopText,#mermaid-svg-bqnrbsisyc9Ih9xg .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-bqnrbsisyc9Ih9xg .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-bqnrbsisyc9Ih9xg .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-bqnrbsisyc9Ih9xg .noteText,#mermaid-svg-bqnrbsisyc9Ih9xg .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-bqnrbsisyc9Ih9xg .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-bqnrbsisyc9Ih9xg .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-bqnrbsisyc9Ih9xg .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-bqnrbsisyc9Ih9xg .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg .section{stroke:none;opacity:0.2}#mermaid-svg-bqnrbsisyc9Ih9xg .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-bqnrbsisyc9Ih9xg .section2{fill:#fff400}#mermaid-svg-bqnrbsisyc9Ih9xg .section1,#mermaid-svg-bqnrbsisyc9Ih9xg .section3{fill:#fff;opacity:0.2}#mermaid-svg-bqnrbsisyc9Ih9xg .sectionTitle0{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .sectionTitle1{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .sectionTitle2{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .sectionTitle3{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-bqnrbsisyc9Ih9xg .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg .grid path{stroke-width:0}#mermaid-svg-bqnrbsisyc9Ih9xg .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-bqnrbsisyc9Ih9xg .task{stroke-width:2}#mermaid-svg-bqnrbsisyc9Ih9xg .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg .taskText:not([font-size]){font-size:11px}#mermaid-svg-bqnrbsisyc9Ih9xg .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-bqnrbsisyc9Ih9xg .task.clickable{cursor:pointer}#mermaid-svg-bqnrbsisyc9Ih9xg .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-bqnrbsisyc9Ih9xg .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-bqnrbsisyc9Ih9xg .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-bqnrbsisyc9Ih9xg .taskText0,#mermaid-svg-bqnrbsisyc9Ih9xg .taskText1,#mermaid-svg-bqnrbsisyc9Ih9xg .taskText2,#mermaid-svg-bqnrbsisyc9Ih9xg .taskText3{fill:#fff}#mermaid-svg-bqnrbsisyc9Ih9xg .task0,#mermaid-svg-bqnrbsisyc9Ih9xg .task1,#mermaid-svg-bqnrbsisyc9Ih9xg .task2,#mermaid-svg-bqnrbsisyc9Ih9xg .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-bqnrbsisyc9Ih9xg .taskTextOutside0,#mermaid-svg-bqnrbsisyc9Ih9xg .taskTextOutside2{fill:#000}#mermaid-svg-bqnrbsisyc9Ih9xg .taskTextOutside1,#mermaid-svg-bqnrbsisyc9Ih9xg .taskTextOutside3{fill:#000}#mermaid-svg-bqnrbsisyc9Ih9xg .active0,#mermaid-svg-bqnrbsisyc9Ih9xg .active1,#mermaid-svg-bqnrbsisyc9Ih9xg .active2,#mermaid-svg-bqnrbsisyc9Ih9xg .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-bqnrbsisyc9Ih9xg .activeText0,#mermaid-svg-bqnrbsisyc9Ih9xg .activeText1,#mermaid-svg-bqnrbsisyc9Ih9xg .activeText2,#mermaid-svg-bqnrbsisyc9Ih9xg .activeText3{fill:#000 !important}#mermaid-svg-bqnrbsisyc9Ih9xg .done0,#mermaid-svg-bqnrbsisyc9Ih9xg .done1,#mermaid-svg-bqnrbsisyc9Ih9xg .done2,#mermaid-svg-bqnrbsisyc9Ih9xg .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-bqnrbsisyc9Ih9xg .doneText0,#mermaid-svg-bqnrbsisyc9Ih9xg .doneText1,#mermaid-svg-bqnrbsisyc9Ih9xg .doneText2,#mermaid-svg-bqnrbsisyc9Ih9xg .doneText3{fill:#000 !important}#mermaid-svg-bqnrbsisyc9Ih9xg .crit0,#mermaid-svg-bqnrbsisyc9Ih9xg .crit1,#mermaid-svg-bqnrbsisyc9Ih9xg .crit2,#mermaid-svg-bqnrbsisyc9Ih9xg .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-bqnrbsisyc9Ih9xg .activeCrit0,#mermaid-svg-bqnrbsisyc9Ih9xg .activeCrit1,#mermaid-svg-bqnrbsisyc9Ih9xg .activeCrit2,#mermaid-svg-bqnrbsisyc9Ih9xg .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-bqnrbsisyc9Ih9xg .doneCrit0,#mermaid-svg-bqnrbsisyc9Ih9xg .doneCrit1,#mermaid-svg-bqnrbsisyc9Ih9xg .doneCrit2,#mermaid-svg-bqnrbsisyc9Ih9xg .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-bqnrbsisyc9Ih9xg .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-bqnrbsisyc9Ih9xg .milestoneText{font-style:italic}#mermaid-svg-bqnrbsisyc9Ih9xg .doneCritText0,#mermaid-svg-bqnrbsisyc9Ih9xg .doneCritText1,#mermaid-svg-bqnrbsisyc9Ih9xg .doneCritText2,#mermaid-svg-bqnrbsisyc9Ih9xg .doneCritText3{fill:#000 !important}#mermaid-svg-bqnrbsisyc9Ih9xg .activeCritText0,#mermaid-svg-bqnrbsisyc9Ih9xg .activeCritText1,#mermaid-svg-bqnrbsisyc9Ih9xg .activeCritText2,#mermaid-svg-bqnrbsisyc9Ih9xg .activeCritText3{fill:#000 !important}#mermaid-svg-bqnrbsisyc9Ih9xg .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-bqnrbsisyc9Ih9xg g.classGroup text .title{font-weight:bolder}#mermaid-svg-bqnrbsisyc9Ih9xg g.clickable{cursor:pointer}#mermaid-svg-bqnrbsisyc9Ih9xg g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-bqnrbsisyc9Ih9xg g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-bqnrbsisyc9Ih9xg .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-bqnrbsisyc9Ih9xg .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-bqnrbsisyc9Ih9xg .dashed-line{stroke-dasharray:3}#mermaid-svg-bqnrbsisyc9Ih9xg #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg .commit-id,#mermaid-svg-bqnrbsisyc9Ih9xg .commit-msg,#mermaid-svg-bqnrbsisyc9Ih9xg .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-bqnrbsisyc9Ih9xg g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-bqnrbsisyc9Ih9xg g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-bqnrbsisyc9Ih9xg g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-bqnrbsisyc9Ih9xg .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-bqnrbsisyc9Ih9xg .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-bqnrbsisyc9Ih9xg .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-bqnrbsisyc9Ih9xg .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-bqnrbsisyc9Ih9xg .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-bqnrbsisyc9Ih9xg .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-bqnrbsisyc9Ih9xg .edgeLabel text{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bqnrbsisyc9Ih9xg .node circle.state-start{fill:black;stroke:black}#mermaid-svg-bqnrbsisyc9Ih9xg .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-bqnrbsisyc9Ih9xg #statediagram-barbEnd{fill:#9370db}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-state .divider{stroke:#9370db}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-bqnrbsisyc9Ih9xg .note-edge{stroke-dasharray:5}#mermaid-svg-bqnrbsisyc9Ih9xg .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-bqnrbsisyc9Ih9xg .error-icon{fill:#522}#mermaid-svg-bqnrbsisyc9Ih9xg .error-text{fill:#522;stroke:#522}#mermaid-svg-bqnrbsisyc9Ih9xg .edge-thickness-normal{stroke-width:2px}#mermaid-svg-bqnrbsisyc9Ih9xg .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-bqnrbsisyc9Ih9xg .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-bqnrbsisyc9Ih9xg .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-bqnrbsisyc9Ih9xg .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-bqnrbsisyc9Ih9xg .marker{fill:#333}#mermaid-svg-bqnrbsisyc9Ih9xg .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-bqnrbsisyc9Ih9xg { color: rgba(0, 0, 0, 0.75); font: ; }</style>
1.完成任務
2.扣減商戶費用
3.增加用戶余額
用戶
結算系統
商戶系統
用戶系統
  • 補償流程
<style>#mermaid-svg-C47bra91n56VAOpN .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-C47bra91n56VAOpN .label text{fill:#333}#mermaid-svg-C47bra91n56VAOpN .node rect,#mermaid-svg-C47bra91n56VAOpN .node circle,#mermaid-svg-C47bra91n56VAOpN .node ellipse,#mermaid-svg-C47bra91n56VAOpN .node polygon,#mermaid-svg-C47bra91n56VAOpN .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-C47bra91n56VAOpN .node .label{text-align:center;fill:#333}#mermaid-svg-C47bra91n56VAOpN .node.clickable{cursor:pointer}#mermaid-svg-C47bra91n56VAOpN .arrowheadPath{fill:#333}#mermaid-svg-C47bra91n56VAOpN .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-C47bra91n56VAOpN .flowchart-link{stroke:#333;fill:none}#mermaid-svg-C47bra91n56VAOpN .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-C47bra91n56VAOpN .edgeLabel rect{opacity:0.9}#mermaid-svg-C47bra91n56VAOpN .edgeLabel span{color:#333}#mermaid-svg-C47bra91n56VAOpN .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-C47bra91n56VAOpN .cluster text{fill:#333}#mermaid-svg-C47bra91n56VAOpN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-C47bra91n56VAOpN .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-C47bra91n56VAOpN text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-C47bra91n56VAOpN .actor-line{stroke:grey}#mermaid-svg-C47bra91n56VAOpN .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-C47bra91n56VAOpN .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-C47bra91n56VAOpN #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-C47bra91n56VAOpN .sequenceNumber{fill:#fff}#mermaid-svg-C47bra91n56VAOpN #sequencenumber{fill:#333}#mermaid-svg-C47bra91n56VAOpN #crosshead path{fill:#333;stroke:#333}#mermaid-svg-C47bra91n56VAOpN .messageText{fill:#333;stroke:#333}#mermaid-svg-C47bra91n56VAOpN .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-C47bra91n56VAOpN .labelText,#mermaid-svg-C47bra91n56VAOpN .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-C47bra91n56VAOpN .loopText,#mermaid-svg-C47bra91n56VAOpN .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-C47bra91n56VAOpN .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-C47bra91n56VAOpN .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-C47bra91n56VAOpN .noteText,#mermaid-svg-C47bra91n56VAOpN .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-C47bra91n56VAOpN .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-C47bra91n56VAOpN .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-C47bra91n56VAOpN .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-C47bra91n56VAOpN .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN .section{stroke:none;opacity:0.2}#mermaid-svg-C47bra91n56VAOpN .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-C47bra91n56VAOpN .section2{fill:#fff400}#mermaid-svg-C47bra91n56VAOpN .section1,#mermaid-svg-C47bra91n56VAOpN .section3{fill:#fff;opacity:0.2}#mermaid-svg-C47bra91n56VAOpN .sectionTitle0{fill:#333}#mermaid-svg-C47bra91n56VAOpN .sectionTitle1{fill:#333}#mermaid-svg-C47bra91n56VAOpN .sectionTitle2{fill:#333}#mermaid-svg-C47bra91n56VAOpN .sectionTitle3{fill:#333}#mermaid-svg-C47bra91n56VAOpN .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-C47bra91n56VAOpN .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN .grid path{stroke-width:0}#mermaid-svg-C47bra91n56VAOpN .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-C47bra91n56VAOpN .task{stroke-width:2}#mermaid-svg-C47bra91n56VAOpN .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN .taskText:not([font-size]){font-size:11px}#mermaid-svg-C47bra91n56VAOpN .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-C47bra91n56VAOpN .task.clickable{cursor:pointer}#mermaid-svg-C47bra91n56VAOpN .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-C47bra91n56VAOpN .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-C47bra91n56VAOpN .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-C47bra91n56VAOpN .taskText0,#mermaid-svg-C47bra91n56VAOpN .taskText1,#mermaid-svg-C47bra91n56VAOpN .taskText2,#mermaid-svg-C47bra91n56VAOpN .taskText3{fill:#fff}#mermaid-svg-C47bra91n56VAOpN .task0,#mermaid-svg-C47bra91n56VAOpN .task1,#mermaid-svg-C47bra91n56VAOpN .task2,#mermaid-svg-C47bra91n56VAOpN .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-C47bra91n56VAOpN .taskTextOutside0,#mermaid-svg-C47bra91n56VAOpN .taskTextOutside2{fill:#000}#mermaid-svg-C47bra91n56VAOpN .taskTextOutside1,#mermaid-svg-C47bra91n56VAOpN .taskTextOutside3{fill:#000}#mermaid-svg-C47bra91n56VAOpN .active0,#mermaid-svg-C47bra91n56VAOpN .active1,#mermaid-svg-C47bra91n56VAOpN .active2,#mermaid-svg-C47bra91n56VAOpN .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-C47bra91n56VAOpN .activeText0,#mermaid-svg-C47bra91n56VAOpN .activeText1,#mermaid-svg-C47bra91n56VAOpN .activeText2,#mermaid-svg-C47bra91n56VAOpN .activeText3{fill:#000 !important}#mermaid-svg-C47bra91n56VAOpN .done0,#mermaid-svg-C47bra91n56VAOpN .done1,#mermaid-svg-C47bra91n56VAOpN .done2,#mermaid-svg-C47bra91n56VAOpN .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-C47bra91n56VAOpN .doneText0,#mermaid-svg-C47bra91n56VAOpN .doneText1,#mermaid-svg-C47bra91n56VAOpN .doneText2,#mermaid-svg-C47bra91n56VAOpN .doneText3{fill:#000 !important}#mermaid-svg-C47bra91n56VAOpN .crit0,#mermaid-svg-C47bra91n56VAOpN .crit1,#mermaid-svg-C47bra91n56VAOpN .crit2,#mermaid-svg-C47bra91n56VAOpN .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-C47bra91n56VAOpN .activeCrit0,#mermaid-svg-C47bra91n56VAOpN .activeCrit1,#mermaid-svg-C47bra91n56VAOpN .activeCrit2,#mermaid-svg-C47bra91n56VAOpN .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-C47bra91n56VAOpN .doneCrit0,#mermaid-svg-C47bra91n56VAOpN .doneCrit1,#mermaid-svg-C47bra91n56VAOpN .doneCrit2,#mermaid-svg-C47bra91n56VAOpN .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-C47bra91n56VAOpN .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-C47bra91n56VAOpN .milestoneText{font-style:italic}#mermaid-svg-C47bra91n56VAOpN .doneCritText0,#mermaid-svg-C47bra91n56VAOpN .doneCritText1,#mermaid-svg-C47bra91n56VAOpN .doneCritText2,#mermaid-svg-C47bra91n56VAOpN .doneCritText3{fill:#000 !important}#mermaid-svg-C47bra91n56VAOpN .activeCritText0,#mermaid-svg-C47bra91n56VAOpN .activeCritText1,#mermaid-svg-C47bra91n56VAOpN .activeCritText2,#mermaid-svg-C47bra91n56VAOpN .activeCritText3{fill:#000 !important}#mermaid-svg-C47bra91n56VAOpN .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-C47bra91n56VAOpN g.classGroup text .title{font-weight:bolder}#mermaid-svg-C47bra91n56VAOpN g.clickable{cursor:pointer}#mermaid-svg-C47bra91n56VAOpN g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-C47bra91n56VAOpN g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-C47bra91n56VAOpN .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-C47bra91n56VAOpN .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-C47bra91n56VAOpN .dashed-line{stroke-dasharray:3}#mermaid-svg-C47bra91n56VAOpN #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN .commit-id,#mermaid-svg-C47bra91n56VAOpN .commit-msg,#mermaid-svg-C47bra91n56VAOpN .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-C47bra91n56VAOpN g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-C47bra91n56VAOpN g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-C47bra91n56VAOpN g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-C47bra91n56VAOpN g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-C47bra91n56VAOpN .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-C47bra91n56VAOpN .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-C47bra91n56VAOpN .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-C47bra91n56VAOpN .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-C47bra91n56VAOpN .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-C47bra91n56VAOpN .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-C47bra91n56VAOpN .edgeLabel text{fill:#333}#mermaid-svg-C47bra91n56VAOpN .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-C47bra91n56VAOpN .node circle.state-start{fill:black;stroke:black}#mermaid-svg-C47bra91n56VAOpN .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-C47bra91n56VAOpN #statediagram-barbEnd{fill:#9370db}#mermaid-svg-C47bra91n56VAOpN .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-C47bra91n56VAOpN .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-C47bra91n56VAOpN .statediagram-state .divider{stroke:#9370db}#mermaid-svg-C47bra91n56VAOpN .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-C47bra91n56VAOpN .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-C47bra91n56VAOpN .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-C47bra91n56VAOpN .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-C47bra91n56VAOpN .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-C47bra91n56VAOpN .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-C47bra91n56VAOpN .note-edge{stroke-dasharray:5}#mermaid-svg-C47bra91n56VAOpN .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-C47bra91n56VAOpN .error-icon{fill:#522}#mermaid-svg-C47bra91n56VAOpN .error-text{fill:#522;stroke:#522}#mermaid-svg-C47bra91n56VAOpN .edge-thickness-normal{stroke-width:2px}#mermaid-svg-C47bra91n56VAOpN .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-C47bra91n56VAOpN .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-C47bra91n56VAOpN .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-C47bra91n56VAOpN .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-C47bra91n56VAOpN .marker{fill:#333}#mermaid-svg-C47bra91n56VAOpN .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-C47bra91n56VAOpN { color: rgba(0, 0, 0, 0.75); font: ; }</style>
輪詢訂單狀態
扣減
結算
定時任務
結算狀態
商戶扣減失敗
結束
用戶未結算

場景Q&A

  • Q:商戶扣款失敗或者商戶扣款成功,用戶結算失敗怎么辦?

    A: 定時任務根據結算狀態進行結算流程驅動,會一直輪詢補償嘗試結算用戶,直到成功,

  • Q:商戶扣款成功,用戶結算失敗為何不進行做業務超時的逆向流程回滾商家扣款?

    A: 用戶做任務時一定是做了前置校驗進行平臺任務發放的,也就是說用戶任務只要完成必須要進行結算,這是一個不能逆向的流程,即使極端情況下商戶余額空了暫時無法結算到用戶也要一直重試,一旦商戶余額充足則繼續整個結算流程,

場景:運營活動抽獎

在這里插入圖片描述

專案背景

抽獎是運營活動中比較常見的方式,對于用戶來說需要做的是參加設定人物獲取積分,攢夠積分就可以開始抽獎,抽中后即等待獎品入賬,一般券會立刻入賬使用,而實物商品則需要耐心等待物流送到用戶手上,

分布式事務

關于抽獎,涉及賬戶動賬、庫存參與次數扣減、抽獎等多個環節,該場景要解決的分布式事務是賬戶動賬、活動庫存變更、抽獎下單資料一致性

設計方案

資料系統操作
賬戶余額交易系統扣減賬戶余額
活動庫存運營活動系統扣減庫存、用戶日參&總參
業務流水運營活動系統業務ID[動賬憑證],抽獎ID[抽獎憑證],活動ID
抽獎流水抽獎系統抽獎下單,獲取中獎結果
  • 互動流程
<style>#mermaid-svg-XD3uQLr1HwZpdDZL .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .label text{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .node rect,#mermaid-svg-XD3uQLr1HwZpdDZL .node circle,#mermaid-svg-XD3uQLr1HwZpdDZL .node ellipse,#mermaid-svg-XD3uQLr1HwZpdDZL .node polygon,#mermaid-svg-XD3uQLr1HwZpdDZL .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-XD3uQLr1HwZpdDZL .node .label{text-align:center;fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .node.clickable{cursor:pointer}#mermaid-svg-XD3uQLr1HwZpdDZL .arrowheadPath{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-XD3uQLr1HwZpdDZL .flowchart-link{stroke:#333;fill:none}#mermaid-svg-XD3uQLr1HwZpdDZL .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-XD3uQLr1HwZpdDZL .edgeLabel rect{opacity:0.9}#mermaid-svg-XD3uQLr1HwZpdDZL .edgeLabel span{color:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-XD3uQLr1HwZpdDZL .cluster text{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-XD3uQLr1HwZpdDZL .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-XD3uQLr1HwZpdDZL text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-XD3uQLr1HwZpdDZL .actor-line{stroke:grey}#mermaid-svg-XD3uQLr1HwZpdDZL .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-XD3uQLr1HwZpdDZL #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .sequenceNumber{fill:#fff}#mermaid-svg-XD3uQLr1HwZpdDZL #sequencenumber{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL #crosshead path{fill:#333;stroke:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .messageText{fill:#333;stroke:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-XD3uQLr1HwZpdDZL .labelText,#mermaid-svg-XD3uQLr1HwZpdDZL .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-XD3uQLr1HwZpdDZL .loopText,#mermaid-svg-XD3uQLr1HwZpdDZL .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-XD3uQLr1HwZpdDZL .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-XD3uQLr1HwZpdDZL .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-XD3uQLr1HwZpdDZL .noteText,#mermaid-svg-XD3uQLr1HwZpdDZL .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-XD3uQLr1HwZpdDZL .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-XD3uQLr1HwZpdDZL .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-XD3uQLr1HwZpdDZL .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-XD3uQLr1HwZpdDZL .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL .section{stroke:none;opacity:0.2}#mermaid-svg-XD3uQLr1HwZpdDZL .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-XD3uQLr1HwZpdDZL .section2{fill:#fff400}#mermaid-svg-XD3uQLr1HwZpdDZL .section1,#mermaid-svg-XD3uQLr1HwZpdDZL .section3{fill:#fff;opacity:0.2}#mermaid-svg-XD3uQLr1HwZpdDZL .sectionTitle0{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .sectionTitle1{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .sectionTitle2{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .sectionTitle3{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-XD3uQLr1HwZpdDZL .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL .grid path{stroke-width:0}#mermaid-svg-XD3uQLr1HwZpdDZL .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-XD3uQLr1HwZpdDZL .task{stroke-width:2}#mermaid-svg-XD3uQLr1HwZpdDZL .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL .taskText:not([font-size]){font-size:11px}#mermaid-svg-XD3uQLr1HwZpdDZL .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-XD3uQLr1HwZpdDZL .task.clickable{cursor:pointer}#mermaid-svg-XD3uQLr1HwZpdDZL .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-XD3uQLr1HwZpdDZL .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-XD3uQLr1HwZpdDZL .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-XD3uQLr1HwZpdDZL .taskText0,#mermaid-svg-XD3uQLr1HwZpdDZL .taskText1,#mermaid-svg-XD3uQLr1HwZpdDZL .taskText2,#mermaid-svg-XD3uQLr1HwZpdDZL .taskText3{fill:#fff}#mermaid-svg-XD3uQLr1HwZpdDZL .task0,#mermaid-svg-XD3uQLr1HwZpdDZL .task1,#mermaid-svg-XD3uQLr1HwZpdDZL .task2,#mermaid-svg-XD3uQLr1HwZpdDZL .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-XD3uQLr1HwZpdDZL .taskTextOutside0,#mermaid-svg-XD3uQLr1HwZpdDZL .taskTextOutside2{fill:#000}#mermaid-svg-XD3uQLr1HwZpdDZL .taskTextOutside1,#mermaid-svg-XD3uQLr1HwZpdDZL .taskTextOutside3{fill:#000}#mermaid-svg-XD3uQLr1HwZpdDZL .active0,#mermaid-svg-XD3uQLr1HwZpdDZL .active1,#mermaid-svg-XD3uQLr1HwZpdDZL .active2,#mermaid-svg-XD3uQLr1HwZpdDZL .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-XD3uQLr1HwZpdDZL .activeText0,#mermaid-svg-XD3uQLr1HwZpdDZL .activeText1,#mermaid-svg-XD3uQLr1HwZpdDZL .activeText2,#mermaid-svg-XD3uQLr1HwZpdDZL .activeText3{fill:#000 !important}#mermaid-svg-XD3uQLr1HwZpdDZL .done0,#mermaid-svg-XD3uQLr1HwZpdDZL .done1,#mermaid-svg-XD3uQLr1HwZpdDZL .done2,#mermaid-svg-XD3uQLr1HwZpdDZL .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-XD3uQLr1HwZpdDZL .doneText0,#mermaid-svg-XD3uQLr1HwZpdDZL .doneText1,#mermaid-svg-XD3uQLr1HwZpdDZL .doneText2,#mermaid-svg-XD3uQLr1HwZpdDZL .doneText3{fill:#000 !important}#mermaid-svg-XD3uQLr1HwZpdDZL .crit0,#mermaid-svg-XD3uQLr1HwZpdDZL .crit1,#mermaid-svg-XD3uQLr1HwZpdDZL .crit2,#mermaid-svg-XD3uQLr1HwZpdDZL .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-XD3uQLr1HwZpdDZL .activeCrit0,#mermaid-svg-XD3uQLr1HwZpdDZL .activeCrit1,#mermaid-svg-XD3uQLr1HwZpdDZL .activeCrit2,#mermaid-svg-XD3uQLr1HwZpdDZL .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-XD3uQLr1HwZpdDZL .doneCrit0,#mermaid-svg-XD3uQLr1HwZpdDZL .doneCrit1,#mermaid-svg-XD3uQLr1HwZpdDZL .doneCrit2,#mermaid-svg-XD3uQLr1HwZpdDZL .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-XD3uQLr1HwZpdDZL .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-XD3uQLr1HwZpdDZL .milestoneText{font-style:italic}#mermaid-svg-XD3uQLr1HwZpdDZL .doneCritText0,#mermaid-svg-XD3uQLr1HwZpdDZL .doneCritText1,#mermaid-svg-XD3uQLr1HwZpdDZL .doneCritText2,#mermaid-svg-XD3uQLr1HwZpdDZL .doneCritText3{fill:#000 !important}#mermaid-svg-XD3uQLr1HwZpdDZL .activeCritText0,#mermaid-svg-XD3uQLr1HwZpdDZL .activeCritText1,#mermaid-svg-XD3uQLr1HwZpdDZL .activeCritText2,#mermaid-svg-XD3uQLr1HwZpdDZL .activeCritText3{fill:#000 !important}#mermaid-svg-XD3uQLr1HwZpdDZL .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-XD3uQLr1HwZpdDZL g.classGroup text .title{font-weight:bolder}#mermaid-svg-XD3uQLr1HwZpdDZL g.clickable{cursor:pointer}#mermaid-svg-XD3uQLr1HwZpdDZL g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-XD3uQLr1HwZpdDZL g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-XD3uQLr1HwZpdDZL .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-XD3uQLr1HwZpdDZL .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-XD3uQLr1HwZpdDZL .dashed-line{stroke-dasharray:3}#mermaid-svg-XD3uQLr1HwZpdDZL #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL .commit-id,#mermaid-svg-XD3uQLr1HwZpdDZL .commit-msg,#mermaid-svg-XD3uQLr1HwZpdDZL .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-XD3uQLr1HwZpdDZL g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-XD3uQLr1HwZpdDZL g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-XD3uQLr1HwZpdDZL g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-XD3uQLr1HwZpdDZL .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-XD3uQLr1HwZpdDZL .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-XD3uQLr1HwZpdDZL .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-XD3uQLr1HwZpdDZL .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-XD3uQLr1HwZpdDZL .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-XD3uQLr1HwZpdDZL .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-XD3uQLr1HwZpdDZL .edgeLabel text{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-XD3uQLr1HwZpdDZL .node circle.state-start{fill:black;stroke:black}#mermaid-svg-XD3uQLr1HwZpdDZL .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-XD3uQLr1HwZpdDZL #statediagram-barbEnd{fill:#9370db}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-state .divider{stroke:#9370db}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-XD3uQLr1HwZpdDZL .note-edge{stroke-dasharray:5}#mermaid-svg-XD3uQLr1HwZpdDZL .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-XD3uQLr1HwZpdDZL .error-icon{fill:#522}#mermaid-svg-XD3uQLr1HwZpdDZL .error-text{fill:#522;stroke:#522}#mermaid-svg-XD3uQLr1HwZpdDZL .edge-thickness-normal{stroke-width:2px}#mermaid-svg-XD3uQLr1HwZpdDZL .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-XD3uQLr1HwZpdDZL .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-XD3uQLr1HwZpdDZL .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-XD3uQLr1HwZpdDZL .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-XD3uQLr1HwZpdDZL .marker{fill:#333}#mermaid-svg-XD3uQLr1HwZpdDZL .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-XD3uQLr1HwZpdDZL { color: rgba(0, 0, 0, 0.75); font: ; }</style>
1.庫存扣減&日參總參累計
2.賬戶動賬
3.抽獎下單
用戶抽獎
運營系統
交易系統
抽獎系統
  • 補償流程
<style>#mermaid-svg-HHT0b0ZFN1MJjGU6 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .label text{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .node rect,#mermaid-svg-HHT0b0ZFN1MJjGU6 .node circle,#mermaid-svg-HHT0b0ZFN1MJjGU6 .node ellipse,#mermaid-svg-HHT0b0ZFN1MJjGU6 .node polygon,#mermaid-svg-HHT0b0ZFN1MJjGU6 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .node .label{text-align:center;fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .node.clickable{cursor:pointer}#mermaid-svg-HHT0b0ZFN1MJjGU6 .arrowheadPath{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edgeLabel rect{opacity:0.9}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edgeLabel span{color:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .cluster text{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-HHT0b0ZFN1MJjGU6 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-HHT0b0ZFN1MJjGU6 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-HHT0b0ZFN1MJjGU6 .actor-line{stroke:grey}#mermaid-svg-HHT0b0ZFN1MJjGU6 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .sequenceNumber{fill:#fff}#mermaid-svg-HHT0b0ZFN1MJjGU6 #sequencenumber{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .messageText{fill:#333;stroke:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-HHT0b0ZFN1MJjGU6 .labelText,#mermaid-svg-HHT0b0ZFN1MJjGU6 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-HHT0b0ZFN1MJjGU6 .loopText,#mermaid-svg-HHT0b0ZFN1MJjGU6 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-HHT0b0ZFN1MJjGU6 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-HHT0b0ZFN1MJjGU6 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-HHT0b0ZFN1MJjGU6 .noteText,#mermaid-svg-HHT0b0ZFN1MJjGU6 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-HHT0b0ZFN1MJjGU6 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-HHT0b0ZFN1MJjGU6 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-HHT0b0ZFN1MJjGU6 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-HHT0b0ZFN1MJjGU6 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .section{stroke:none;opacity:0.2}#mermaid-svg-HHT0b0ZFN1MJjGU6 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .section2{fill:#fff400}#mermaid-svg-HHT0b0ZFN1MJjGU6 .section1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .section3{fill:#fff;opacity:0.2}#mermaid-svg-HHT0b0ZFN1MJjGU6 .sectionTitle0{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .sectionTitle1{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .sectionTitle2{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .sectionTitle3{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-HHT0b0ZFN1MJjGU6 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .grid path{stroke-width:0}#mermaid-svg-HHT0b0ZFN1MJjGU6 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .task{stroke-width:2}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskText:not([font-size]){font-size:11px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .task.clickable{cursor:pointer}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskText0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskText1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskText2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskText3{fill:#fff}#mermaid-svg-HHT0b0ZFN1MJjGU6 .task0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .task1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .task2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskTextOutside0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskTextOutside2{fill:#000}#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskTextOutside1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .taskTextOutside3{fill:#000}#mermaid-svg-HHT0b0ZFN1MJjGU6 .active0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .active1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .active2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeText0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeText1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeText2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeText3{fill:#000 !important}#mermaid-svg-HHT0b0ZFN1MJjGU6 .done0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .done1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .done2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneText0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneText1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneText2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneText3{fill:#000 !important}#mermaid-svg-HHT0b0ZFN1MJjGU6 .crit0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .crit1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .crit2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeCrit0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeCrit1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeCrit2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneCrit0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneCrit1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneCrit2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-HHT0b0ZFN1MJjGU6 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .milestoneText{font-style:italic}#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneCritText0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneCritText1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneCritText2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .doneCritText3{fill:#000 !important}#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeCritText0,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeCritText1,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeCritText2,#mermaid-svg-HHT0b0ZFN1MJjGU6 .activeCritText3{fill:#000 !important}#mermaid-svg-HHT0b0ZFN1MJjGU6 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.classGroup text .title{font-weight:bolder}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.clickable{cursor:pointer}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-HHT0b0ZFN1MJjGU6 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-HHT0b0ZFN1MJjGU6 .dashed-line{stroke-dasharray:3}#mermaid-svg-HHT0b0ZFN1MJjGU6 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 .commit-id,#mermaid-svg-HHT0b0ZFN1MJjGU6 .commit-msg,#mermaid-svg-HHT0b0ZFN1MJjGU6 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-HHT0b0ZFN1MJjGU6 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-HHT0b0ZFN1MJjGU6 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-HHT0b0ZFN1MJjGU6 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-HHT0b0ZFN1MJjGU6 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edgeLabel text{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-HHT0b0ZFN1MJjGU6 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-HHT0b0ZFN1MJjGU6 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-HHT0b0ZFN1MJjGU6 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-HHT0b0ZFN1MJjGU6 .note-edge{stroke-dasharray:5}#mermaid-svg-HHT0b0ZFN1MJjGU6 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-HHT0b0ZFN1MJjGU6 .error-icon{fill:#522}#mermaid-svg-HHT0b0ZFN1MJjGU6 .error-text{fill:#522;stroke:#522}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-HHT0b0ZFN1MJjGU6 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-HHT0b0ZFN1MJjGU6 .marker{fill:#333}#mermaid-svg-HHT0b0ZFN1MJjGU6 .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-HHT0b0ZFN1MJjGU6 { color: rgba(0, 0, 0, 0.75); font: ; }</style>
輪詢業務流水狀態
業務流水關單
業務流水關單&退款
定時任務
動賬狀態
動賬扣減失敗
結束
抽獎下單失敗

場景Q&A

  • Q:動賬扣減失敗,補償流程為何不驅動扣減完成抽獎?

    A: 抽獎業務對于用戶來說實時性要求很高,正向流程沒有完成的話,沒有通過補償流程驅動的必要性了,用戶體驗不好容易產生問題,補償流程只針對賬戶扣減成功扣沒有順利完成抽獎的情況進行賬戶補款即可,而且這部分補款是有延遲的,在C端展示可以優化或者忽略合并掉,保證的是賬戶額度無損,

2. 弱一致性

2.1 最大努力通知 + 訊息重試控制

場景:資料變更同步下游業務方

在這里插入圖片描述

專案背景

系統資料發生變更時,會對外部系統產生一定影響,外部系統需要知道這種資料變化,這便是資料狀態同步的場景,一般來說資料互動可以有推(Push)、拉(Pull) 兩種形式,這里先說推模式,即資料變更方負責將變化通知到資料關注方,

分布式事務

這里要保證的是資料變更在多個應用中的狀態一致

設計方案

角色驅動方式通信方式
資料變更方MQ + RPC 最終一致呼叫介面通知其他系統
資料關注方RPC呼叫成功更新資料提供介面接收資料變更
  • 互動流程
<style>#mermaid-svg-bln5MhWCRrlhh3T0 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .label text{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .node rect,#mermaid-svg-bln5MhWCRrlhh3T0 .node circle,#mermaid-svg-bln5MhWCRrlhh3T0 .node ellipse,#mermaid-svg-bln5MhWCRrlhh3T0 .node polygon,#mermaid-svg-bln5MhWCRrlhh3T0 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-bln5MhWCRrlhh3T0 .node .label{text-align:center;fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .node.clickable{cursor:pointer}#mermaid-svg-bln5MhWCRrlhh3T0 .arrowheadPath{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-bln5MhWCRrlhh3T0 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-bln5MhWCRrlhh3T0 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-bln5MhWCRrlhh3T0 .edgeLabel rect{opacity:0.9}#mermaid-svg-bln5MhWCRrlhh3T0 .edgeLabel span{color:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-bln5MhWCRrlhh3T0 .cluster text{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-bln5MhWCRrlhh3T0 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-bln5MhWCRrlhh3T0 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-bln5MhWCRrlhh3T0 .actor-line{stroke:grey}#mermaid-svg-bln5MhWCRrlhh3T0 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-bln5MhWCRrlhh3T0 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .sequenceNumber{fill:#fff}#mermaid-svg-bln5MhWCRrlhh3T0 #sequencenumber{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .messageText{fill:#333;stroke:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-bln5MhWCRrlhh3T0 .labelText,#mermaid-svg-bln5MhWCRrlhh3T0 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-bln5MhWCRrlhh3T0 .loopText,#mermaid-svg-bln5MhWCRrlhh3T0 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-bln5MhWCRrlhh3T0 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-bln5MhWCRrlhh3T0 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-bln5MhWCRrlhh3T0 .noteText,#mermaid-svg-bln5MhWCRrlhh3T0 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-bln5MhWCRrlhh3T0 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-bln5MhWCRrlhh3T0 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-bln5MhWCRrlhh3T0 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-bln5MhWCRrlhh3T0 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 .section{stroke:none;opacity:0.2}#mermaid-svg-bln5MhWCRrlhh3T0 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-bln5MhWCRrlhh3T0 .section2{fill:#fff400}#mermaid-svg-bln5MhWCRrlhh3T0 .section1,#mermaid-svg-bln5MhWCRrlhh3T0 .section3{fill:#fff;opacity:0.2}#mermaid-svg-bln5MhWCRrlhh3T0 .sectionTitle0{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .sectionTitle1{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .sectionTitle2{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .sectionTitle3{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-bln5MhWCRrlhh3T0 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 .grid path{stroke-width:0}#mermaid-svg-bln5MhWCRrlhh3T0 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-bln5MhWCRrlhh3T0 .task{stroke-width:2}#mermaid-svg-bln5MhWCRrlhh3T0 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 .taskText:not([font-size]){font-size:11px}#mermaid-svg-bln5MhWCRrlhh3T0 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-bln5MhWCRrlhh3T0 .task.clickable{cursor:pointer}#mermaid-svg-bln5MhWCRrlhh3T0 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-bln5MhWCRrlhh3T0 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-bln5MhWCRrlhh3T0 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-bln5MhWCRrlhh3T0 .taskText0,#mermaid-svg-bln5MhWCRrlhh3T0 .taskText1,#mermaid-svg-bln5MhWCRrlhh3T0 .taskText2,#mermaid-svg-bln5MhWCRrlhh3T0 .taskText3{fill:#fff}#mermaid-svg-bln5MhWCRrlhh3T0 .task0,#mermaid-svg-bln5MhWCRrlhh3T0 .task1,#mermaid-svg-bln5MhWCRrlhh3T0 .task2,#mermaid-svg-bln5MhWCRrlhh3T0 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-bln5MhWCRrlhh3T0 .taskTextOutside0,#mermaid-svg-bln5MhWCRrlhh3T0 .taskTextOutside2{fill:#000}#mermaid-svg-bln5MhWCRrlhh3T0 .taskTextOutside1,#mermaid-svg-bln5MhWCRrlhh3T0 .taskTextOutside3{fill:#000}#mermaid-svg-bln5MhWCRrlhh3T0 .active0,#mermaid-svg-bln5MhWCRrlhh3T0 .active1,#mermaid-svg-bln5MhWCRrlhh3T0 .active2,#mermaid-svg-bln5MhWCRrlhh3T0 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-bln5MhWCRrlhh3T0 .activeText0,#mermaid-svg-bln5MhWCRrlhh3T0 .activeText1,#mermaid-svg-bln5MhWCRrlhh3T0 .activeText2,#mermaid-svg-bln5MhWCRrlhh3T0 .activeText3{fill:#000 !important}#mermaid-svg-bln5MhWCRrlhh3T0 .done0,#mermaid-svg-bln5MhWCRrlhh3T0 .done1,#mermaid-svg-bln5MhWCRrlhh3T0 .done2,#mermaid-svg-bln5MhWCRrlhh3T0 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-bln5MhWCRrlhh3T0 .doneText0,#mermaid-svg-bln5MhWCRrlhh3T0 .doneText1,#mermaid-svg-bln5MhWCRrlhh3T0 .doneText2,#mermaid-svg-bln5MhWCRrlhh3T0 .doneText3{fill:#000 !important}#mermaid-svg-bln5MhWCRrlhh3T0 .crit0,#mermaid-svg-bln5MhWCRrlhh3T0 .crit1,#mermaid-svg-bln5MhWCRrlhh3T0 .crit2,#mermaid-svg-bln5MhWCRrlhh3T0 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-bln5MhWCRrlhh3T0 .activeCrit0,#mermaid-svg-bln5MhWCRrlhh3T0 .activeCrit1,#mermaid-svg-bln5MhWCRrlhh3T0 .activeCrit2,#mermaid-svg-bln5MhWCRrlhh3T0 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-bln5MhWCRrlhh3T0 .doneCrit0,#mermaid-svg-bln5MhWCRrlhh3T0 .doneCrit1,#mermaid-svg-bln5MhWCRrlhh3T0 .doneCrit2,#mermaid-svg-bln5MhWCRrlhh3T0 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-bln5MhWCRrlhh3T0 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-bln5MhWCRrlhh3T0 .milestoneText{font-style:italic}#mermaid-svg-bln5MhWCRrlhh3T0 .doneCritText0,#mermaid-svg-bln5MhWCRrlhh3T0 .doneCritText1,#mermaid-svg-bln5MhWCRrlhh3T0 .doneCritText2,#mermaid-svg-bln5MhWCRrlhh3T0 .doneCritText3{fill:#000 !important}#mermaid-svg-bln5MhWCRrlhh3T0 .activeCritText0,#mermaid-svg-bln5MhWCRrlhh3T0 .activeCritText1,#mermaid-svg-bln5MhWCRrlhh3T0 .activeCritText2,#mermaid-svg-bln5MhWCRrlhh3T0 .activeCritText3{fill:#000 !important}#mermaid-svg-bln5MhWCRrlhh3T0 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-bln5MhWCRrlhh3T0 g.classGroup text .title{font-weight:bolder}#mermaid-svg-bln5MhWCRrlhh3T0 g.clickable{cursor:pointer}#mermaid-svg-bln5MhWCRrlhh3T0 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-bln5MhWCRrlhh3T0 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-bln5MhWCRrlhh3T0 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-bln5MhWCRrlhh3T0 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-bln5MhWCRrlhh3T0 .dashed-line{stroke-dasharray:3}#mermaid-svg-bln5MhWCRrlhh3T0 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 .commit-id,#mermaid-svg-bln5MhWCRrlhh3T0 .commit-msg,#mermaid-svg-bln5MhWCRrlhh3T0 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-bln5MhWCRrlhh3T0 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-bln5MhWCRrlhh3T0 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-bln5MhWCRrlhh3T0 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-bln5MhWCRrlhh3T0 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-bln5MhWCRrlhh3T0 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-bln5MhWCRrlhh3T0 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-bln5MhWCRrlhh3T0 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-bln5MhWCRrlhh3T0 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-bln5MhWCRrlhh3T0 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-bln5MhWCRrlhh3T0 .edgeLabel text{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-bln5MhWCRrlhh3T0 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-bln5MhWCRrlhh3T0 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-bln5MhWCRrlhh3T0 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-bln5MhWCRrlhh3T0 .note-edge{stroke-dasharray:5}#mermaid-svg-bln5MhWCRrlhh3T0 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-bln5MhWCRrlhh3T0 .error-icon{fill:#522}#mermaid-svg-bln5MhWCRrlhh3T0 .error-text{fill:#522;stroke:#522}#mermaid-svg-bln5MhWCRrlhh3T0 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-bln5MhWCRrlhh3T0 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-bln5MhWCRrlhh3T0 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-bln5MhWCRrlhh3T0 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-bln5MhWCRrlhh3T0 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-bln5MhWCRrlhh3T0 .marker{fill:#333}#mermaid-svg-bln5MhWCRrlhh3T0 .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-bln5MhWCRrlhh3T0 { color: rgba(0, 0, 0, 0.75); font: ; }</style>
RPC
retry
RPC
retry
RPC
retry
資料變更
MQ
業務A
MQ
業務B
MQ
業務C

場景Q&A

這里是弱一致性的實作,沒有做本地事務表和定時任務輪詢對比各事務狀態進行補償操作,完全依賴于MQ的失敗重試驅動,若RPC呼叫失敗即資料同步業務方失敗,MQ會一直進行重試操作,隨著重試次數增加,重試間隔也會增加,這里也可以業務自行進行最大努力嘗試次數的控制,超過多少次嘗試仍失敗則放棄,因此不能保證最終一致

場景:資料變更廣播下游業務方

在這里插入圖片描述

專案背景

這里是資料同步的說拉模式,即資料關注方對資料變更方進行資料狀態變更的監聽,這種處理方式處理的主動權在于資料關注方,資料變更方只負責和保證一定通知到資料變更情況,是否能夠同步成功則由監聽方處理和兼容,

分布式事務

這里要保證的是資料變更在多個應用中的狀態一致

設計方案

角色驅動方式通信方式
資料變更方生產MQ資料變更存入MQ佇列
資料關注方監聽MQ消費MQ處理資料變更情況
  • 互動流程
<style>#mermaid-svg-WjhGBQSOp2fpngK5 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .label text{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .node rect,#mermaid-svg-WjhGBQSOp2fpngK5 .node circle,#mermaid-svg-WjhGBQSOp2fpngK5 .node ellipse,#mermaid-svg-WjhGBQSOp2fpngK5 .node polygon,#mermaid-svg-WjhGBQSOp2fpngK5 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-WjhGBQSOp2fpngK5 .node .label{text-align:center;fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .node.clickable{cursor:pointer}#mermaid-svg-WjhGBQSOp2fpngK5 .arrowheadPath{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-WjhGBQSOp2fpngK5 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-WjhGBQSOp2fpngK5 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-WjhGBQSOp2fpngK5 .edgeLabel rect{opacity:0.9}#mermaid-svg-WjhGBQSOp2fpngK5 .edgeLabel span{color:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-WjhGBQSOp2fpngK5 .cluster text{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-WjhGBQSOp2fpngK5 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-WjhGBQSOp2fpngK5 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-WjhGBQSOp2fpngK5 .actor-line{stroke:grey}#mermaid-svg-WjhGBQSOp2fpngK5 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-WjhGBQSOp2fpngK5 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .sequenceNumber{fill:#fff}#mermaid-svg-WjhGBQSOp2fpngK5 #sequencenumber{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .messageText{fill:#333;stroke:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-WjhGBQSOp2fpngK5 .labelText,#mermaid-svg-WjhGBQSOp2fpngK5 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-WjhGBQSOp2fpngK5 .loopText,#mermaid-svg-WjhGBQSOp2fpngK5 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-WjhGBQSOp2fpngK5 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-WjhGBQSOp2fpngK5 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-WjhGBQSOp2fpngK5 .noteText,#mermaid-svg-WjhGBQSOp2fpngK5 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-WjhGBQSOp2fpngK5 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-WjhGBQSOp2fpngK5 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-WjhGBQSOp2fpngK5 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-WjhGBQSOp2fpngK5 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 .section{stroke:none;opacity:0.2}#mermaid-svg-WjhGBQSOp2fpngK5 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-WjhGBQSOp2fpngK5 .section2{fill:#fff400}#mermaid-svg-WjhGBQSOp2fpngK5 .section1,#mermaid-svg-WjhGBQSOp2fpngK5 .section3{fill:#fff;opacity:0.2}#mermaid-svg-WjhGBQSOp2fpngK5 .sectionTitle0{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .sectionTitle1{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .sectionTitle2{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .sectionTitle3{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-WjhGBQSOp2fpngK5 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 .grid path{stroke-width:0}#mermaid-svg-WjhGBQSOp2fpngK5 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-WjhGBQSOp2fpngK5 .task{stroke-width:2}#mermaid-svg-WjhGBQSOp2fpngK5 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 .taskText:not([font-size]){font-size:11px}#mermaid-svg-WjhGBQSOp2fpngK5 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-WjhGBQSOp2fpngK5 .task.clickable{cursor:pointer}#mermaid-svg-WjhGBQSOp2fpngK5 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WjhGBQSOp2fpngK5 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WjhGBQSOp2fpngK5 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WjhGBQSOp2fpngK5 .taskText0,#mermaid-svg-WjhGBQSOp2fpngK5 .taskText1,#mermaid-svg-WjhGBQSOp2fpngK5 .taskText2,#mermaid-svg-WjhGBQSOp2fpngK5 .taskText3{fill:#fff}#mermaid-svg-WjhGBQSOp2fpngK5 .task0,#mermaid-svg-WjhGBQSOp2fpngK5 .task1,#mermaid-svg-WjhGBQSOp2fpngK5 .task2,#mermaid-svg-WjhGBQSOp2fpngK5 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-WjhGBQSOp2fpngK5 .taskTextOutside0,#mermaid-svg-WjhGBQSOp2fpngK5 .taskTextOutside2{fill:#000}#mermaid-svg-WjhGBQSOp2fpngK5 .taskTextOutside1,#mermaid-svg-WjhGBQSOp2fpngK5 .taskTextOutside3{fill:#000}#mermaid-svg-WjhGBQSOp2fpngK5 .active0,#mermaid-svg-WjhGBQSOp2fpngK5 .active1,#mermaid-svg-WjhGBQSOp2fpngK5 .active2,#mermaid-svg-WjhGBQSOp2fpngK5 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-WjhGBQSOp2fpngK5 .activeText0,#mermaid-svg-WjhGBQSOp2fpngK5 .activeText1,#mermaid-svg-WjhGBQSOp2fpngK5 .activeText2,#mermaid-svg-WjhGBQSOp2fpngK5 .activeText3{fill:#000 !important}#mermaid-svg-WjhGBQSOp2fpngK5 .done0,#mermaid-svg-WjhGBQSOp2fpngK5 .done1,#mermaid-svg-WjhGBQSOp2fpngK5 .done2,#mermaid-svg-WjhGBQSOp2fpngK5 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-WjhGBQSOp2fpngK5 .doneText0,#mermaid-svg-WjhGBQSOp2fpngK5 .doneText1,#mermaid-svg-WjhGBQSOp2fpngK5 .doneText2,#mermaid-svg-WjhGBQSOp2fpngK5 .doneText3{fill:#000 !important}#mermaid-svg-WjhGBQSOp2fpngK5 .crit0,#mermaid-svg-WjhGBQSOp2fpngK5 .crit1,#mermaid-svg-WjhGBQSOp2fpngK5 .crit2,#mermaid-svg-WjhGBQSOp2fpngK5 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-WjhGBQSOp2fpngK5 .activeCrit0,#mermaid-svg-WjhGBQSOp2fpngK5 .activeCrit1,#mermaid-svg-WjhGBQSOp2fpngK5 .activeCrit2,#mermaid-svg-WjhGBQSOp2fpngK5 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-WjhGBQSOp2fpngK5 .doneCrit0,#mermaid-svg-WjhGBQSOp2fpngK5 .doneCrit1,#mermaid-svg-WjhGBQSOp2fpngK5 .doneCrit2,#mermaid-svg-WjhGBQSOp2fpngK5 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-WjhGBQSOp2fpngK5 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-WjhGBQSOp2fpngK5 .milestoneText{font-style:italic}#mermaid-svg-WjhGBQSOp2fpngK5 .doneCritText0,#mermaid-svg-WjhGBQSOp2fpngK5 .doneCritText1,#mermaid-svg-WjhGBQSOp2fpngK5 .doneCritText2,#mermaid-svg-WjhGBQSOp2fpngK5 .doneCritText3{fill:#000 !important}#mermaid-svg-WjhGBQSOp2fpngK5 .activeCritText0,#mermaid-svg-WjhGBQSOp2fpngK5 .activeCritText1,#mermaid-svg-WjhGBQSOp2fpngK5 .activeCritText2,#mermaid-svg-WjhGBQSOp2fpngK5 .activeCritText3{fill:#000 !important}#mermaid-svg-WjhGBQSOp2fpngK5 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-WjhGBQSOp2fpngK5 g.classGroup text .title{font-weight:bolder}#mermaid-svg-WjhGBQSOp2fpngK5 g.clickable{cursor:pointer}#mermaid-svg-WjhGBQSOp2fpngK5 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-WjhGBQSOp2fpngK5 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-WjhGBQSOp2fpngK5 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-WjhGBQSOp2fpngK5 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-WjhGBQSOp2fpngK5 .dashed-line{stroke-dasharray:3}#mermaid-svg-WjhGBQSOp2fpngK5 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 .commit-id,#mermaid-svg-WjhGBQSOp2fpngK5 .commit-msg,#mermaid-svg-WjhGBQSOp2fpngK5 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-WjhGBQSOp2fpngK5 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-WjhGBQSOp2fpngK5 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-WjhGBQSOp2fpngK5 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-WjhGBQSOp2fpngK5 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-WjhGBQSOp2fpngK5 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-WjhGBQSOp2fpngK5 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-WjhGBQSOp2fpngK5 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-WjhGBQSOp2fpngK5 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-WjhGBQSOp2fpngK5 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-WjhGBQSOp2fpngK5 .edgeLabel text{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WjhGBQSOp2fpngK5 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-WjhGBQSOp2fpngK5 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-WjhGBQSOp2fpngK5 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-WjhGBQSOp2fpngK5 .note-edge{stroke-dasharray:5}#mermaid-svg-WjhGBQSOp2fpngK5 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-WjhGBQSOp2fpngK5 .error-icon{fill:#522}#mermaid-svg-WjhGBQSOp2fpngK5 .error-text{fill:#522;stroke:#522}#mermaid-svg-WjhGBQSOp2fpngK5 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-WjhGBQSOp2fpngK5 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-WjhGBQSOp2fpngK5 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-WjhGBQSOp2fpngK5 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-WjhGBQSOp2fpngK5 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-WjhGBQSOp2fpngK5 .marker{fill:#333}#mermaid-svg-WjhGBQSOp2fpngK5 .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-WjhGBQSOp2fpngK5 { color: rgba(0, 0, 0, 0.75); font: ; }</style>
produce
produce
produce
consume
consume
consume
資料變更
Topic
Queue
Queue
Queue
業務A
業務B
業務C

場景Q&A

這里也是弱一致性的實作,沒有做本地事務表和定時任務輪詢對比各事務狀態進行補償操作,完全依賴于MQ消費方的處理,若消費方處理失敗或在訊息佇列規定時間內沒有消費完畢,則資料無法保證最終一致

2.2 戰略放棄 + 報警 + 人工修復

場景:秒殺庫存回滾

在這里插入圖片描述

專案背景

在秒殺場景中,最復雜的除了解決高并發問題外,最核心的就是活動商品的庫存控制、變更問題,一般商品庫存會初始化到Redis快取中進行管理,秒殺方法會對Redis快取庫存數量進行校驗、扣減操作,通過MQ異步扣減DB庫存,既利用Reids原子操作進行庫存數量操作,又利用快取抗住高并發請求,起到異步削峰的作用,這是秒殺的正向流程,而逆向流程是用戶秒殺到商品預占了庫存,但是沒有及時進行訂單支付或者進行了訂單取消,此時要發起對庫存的恢復操作,

分布式事務

這里的分布式事務是Redis快取庫存與DB庫存數量一致性問題

設計方案

存盤介質庫存操作方式
Redisincr 、decr累計或扣減
DBMQ異步扣減
  • 互動流程
<style>#mermaid-svg-GgQirTD41oQpPUjz .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-GgQirTD41oQpPUjz .label text{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .node rect,#mermaid-svg-GgQirTD41oQpPUjz .node circle,#mermaid-svg-GgQirTD41oQpPUjz .node ellipse,#mermaid-svg-GgQirTD41oQpPUjz .node polygon,#mermaid-svg-GgQirTD41oQpPUjz .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-GgQirTD41oQpPUjz .node .label{text-align:center;fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .node.clickable{cursor:pointer}#mermaid-svg-GgQirTD41oQpPUjz .arrowheadPath{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-GgQirTD41oQpPUjz .flowchart-link{stroke:#333;fill:none}#mermaid-svg-GgQirTD41oQpPUjz .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-GgQirTD41oQpPUjz .edgeLabel rect{opacity:0.9}#mermaid-svg-GgQirTD41oQpPUjz .edgeLabel span{color:#333}#mermaid-svg-GgQirTD41oQpPUjz .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-GgQirTD41oQpPUjz .cluster text{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-GgQirTD41oQpPUjz .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-GgQirTD41oQpPUjz text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-GgQirTD41oQpPUjz .actor-line{stroke:grey}#mermaid-svg-GgQirTD41oQpPUjz .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-GgQirTD41oQpPUjz .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-GgQirTD41oQpPUjz #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-GgQirTD41oQpPUjz .sequenceNumber{fill:#fff}#mermaid-svg-GgQirTD41oQpPUjz #sequencenumber{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz #crosshead path{fill:#333;stroke:#333}#mermaid-svg-GgQirTD41oQpPUjz .messageText{fill:#333;stroke:#333}#mermaid-svg-GgQirTD41oQpPUjz .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-GgQirTD41oQpPUjz .labelText,#mermaid-svg-GgQirTD41oQpPUjz .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-GgQirTD41oQpPUjz .loopText,#mermaid-svg-GgQirTD41oQpPUjz .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-GgQirTD41oQpPUjz .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-GgQirTD41oQpPUjz .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-GgQirTD41oQpPUjz .noteText,#mermaid-svg-GgQirTD41oQpPUjz .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-GgQirTD41oQpPUjz .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-GgQirTD41oQpPUjz .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-GgQirTD41oQpPUjz .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-GgQirTD41oQpPUjz .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz .section{stroke:none;opacity:0.2}#mermaid-svg-GgQirTD41oQpPUjz .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-GgQirTD41oQpPUjz .section2{fill:#fff400}#mermaid-svg-GgQirTD41oQpPUjz .section1,#mermaid-svg-GgQirTD41oQpPUjz .section3{fill:#fff;opacity:0.2}#mermaid-svg-GgQirTD41oQpPUjz .sectionTitle0{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .sectionTitle1{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .sectionTitle2{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .sectionTitle3{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-GgQirTD41oQpPUjz .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz .grid path{stroke-width:0}#mermaid-svg-GgQirTD41oQpPUjz .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-GgQirTD41oQpPUjz .task{stroke-width:2}#mermaid-svg-GgQirTD41oQpPUjz .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz .taskText:not([font-size]){font-size:11px}#mermaid-svg-GgQirTD41oQpPUjz .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-GgQirTD41oQpPUjz .task.clickable{cursor:pointer}#mermaid-svg-GgQirTD41oQpPUjz .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-GgQirTD41oQpPUjz .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-GgQirTD41oQpPUjz .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-GgQirTD41oQpPUjz .taskText0,#mermaid-svg-GgQirTD41oQpPUjz .taskText1,#mermaid-svg-GgQirTD41oQpPUjz .taskText2,#mermaid-svg-GgQirTD41oQpPUjz .taskText3{fill:#fff}#mermaid-svg-GgQirTD41oQpPUjz .task0,#mermaid-svg-GgQirTD41oQpPUjz .task1,#mermaid-svg-GgQirTD41oQpPUjz .task2,#mermaid-svg-GgQirTD41oQpPUjz .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-GgQirTD41oQpPUjz .taskTextOutside0,#mermaid-svg-GgQirTD41oQpPUjz .taskTextOutside2{fill:#000}#mermaid-svg-GgQirTD41oQpPUjz .taskTextOutside1,#mermaid-svg-GgQirTD41oQpPUjz .taskTextOutside3{fill:#000}#mermaid-svg-GgQirTD41oQpPUjz .active0,#mermaid-svg-GgQirTD41oQpPUjz .active1,#mermaid-svg-GgQirTD41oQpPUjz .active2,#mermaid-svg-GgQirTD41oQpPUjz .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-GgQirTD41oQpPUjz .activeText0,#mermaid-svg-GgQirTD41oQpPUjz .activeText1,#mermaid-svg-GgQirTD41oQpPUjz .activeText2,#mermaid-svg-GgQirTD41oQpPUjz .activeText3{fill:#000 !important}#mermaid-svg-GgQirTD41oQpPUjz .done0,#mermaid-svg-GgQirTD41oQpPUjz .done1,#mermaid-svg-GgQirTD41oQpPUjz .done2,#mermaid-svg-GgQirTD41oQpPUjz .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-GgQirTD41oQpPUjz .doneText0,#mermaid-svg-GgQirTD41oQpPUjz .doneText1,#mermaid-svg-GgQirTD41oQpPUjz .doneText2,#mermaid-svg-GgQirTD41oQpPUjz .doneText3{fill:#000 !important}#mermaid-svg-GgQirTD41oQpPUjz .crit0,#mermaid-svg-GgQirTD41oQpPUjz .crit1,#mermaid-svg-GgQirTD41oQpPUjz .crit2,#mermaid-svg-GgQirTD41oQpPUjz .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-GgQirTD41oQpPUjz .activeCrit0,#mermaid-svg-GgQirTD41oQpPUjz .activeCrit1,#mermaid-svg-GgQirTD41oQpPUjz .activeCrit2,#mermaid-svg-GgQirTD41oQpPUjz .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-GgQirTD41oQpPUjz .doneCrit0,#mermaid-svg-GgQirTD41oQpPUjz .doneCrit1,#mermaid-svg-GgQirTD41oQpPUjz .doneCrit2,#mermaid-svg-GgQirTD41oQpPUjz .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-GgQirTD41oQpPUjz .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-GgQirTD41oQpPUjz .milestoneText{font-style:italic}#mermaid-svg-GgQirTD41oQpPUjz .doneCritText0,#mermaid-svg-GgQirTD41oQpPUjz .doneCritText1,#mermaid-svg-GgQirTD41oQpPUjz .doneCritText2,#mermaid-svg-GgQirTD41oQpPUjz .doneCritText3{fill:#000 !important}#mermaid-svg-GgQirTD41oQpPUjz .activeCritText0,#mermaid-svg-GgQirTD41oQpPUjz .activeCritText1,#mermaid-svg-GgQirTD41oQpPUjz .activeCritText2,#mermaid-svg-GgQirTD41oQpPUjz .activeCritText3{fill:#000 !important}#mermaid-svg-GgQirTD41oQpPUjz .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-GgQirTD41oQpPUjz g.classGroup text .title{font-weight:bolder}#mermaid-svg-GgQirTD41oQpPUjz g.clickable{cursor:pointer}#mermaid-svg-GgQirTD41oQpPUjz g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-GgQirTD41oQpPUjz g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-GgQirTD41oQpPUjz .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-GgQirTD41oQpPUjz .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-GgQirTD41oQpPUjz .dashed-line{stroke-dasharray:3}#mermaid-svg-GgQirTD41oQpPUjz #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz .commit-id,#mermaid-svg-GgQirTD41oQpPUjz .commit-msg,#mermaid-svg-GgQirTD41oQpPUjz .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-GgQirTD41oQpPUjz g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-GgQirTD41oQpPUjz g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-GgQirTD41oQpPUjz g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-GgQirTD41oQpPUjz .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-GgQirTD41oQpPUjz .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-GgQirTD41oQpPUjz .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-GgQirTD41oQpPUjz .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-GgQirTD41oQpPUjz .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-GgQirTD41oQpPUjz .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-GgQirTD41oQpPUjz .edgeLabel text{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-GgQirTD41oQpPUjz .node circle.state-start{fill:black;stroke:black}#mermaid-svg-GgQirTD41oQpPUjz .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-GgQirTD41oQpPUjz #statediagram-barbEnd{fill:#9370db}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-state .divider{stroke:#9370db}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-GgQirTD41oQpPUjz .note-edge{stroke-dasharray:5}#mermaid-svg-GgQirTD41oQpPUjz .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-GgQirTD41oQpPUjz .error-icon{fill:#522}#mermaid-svg-GgQirTD41oQpPUjz .error-text{fill:#522;stroke:#522}#mermaid-svg-GgQirTD41oQpPUjz .edge-thickness-normal{stroke-width:2px}#mermaid-svg-GgQirTD41oQpPUjz .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-GgQirTD41oQpPUjz .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-GgQirTD41oQpPUjz .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-GgQirTD41oQpPUjz .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-GgQirTD41oQpPUjz .marker{fill:#333}#mermaid-svg-GgQirTD41oQpPUjz .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-GgQirTD41oQpPUjz { color: rgba(0, 0, 0, 0.75); font: ; }</style>
1.扣減快取庫存
2.1 異步MQ
3.扣減庫存
2.2 創建訂單
秒殺下單
Redis
MQ
DB

場景Q&A

  • Q:秒殺場景會出現哪些分布式問題?

    A: 根據如上流程圖,扣減快取庫存、創建訂單、異步MQ發送是在一個同步的函式方法中的三個非原子的子步驟,而秒殺場景下流量洪峰會一瞬間打滿執行緒,以上三個子步驟任何異步都會出現問題,因為都是先扣快取庫存數量,根據實踐經驗看,極端情況下會出現扣減快取庫存成功了,后面創建訂單失敗了或者異步MQ沒有發出來無法削減DB庫存數量,因此資料結果是快取庫存扣減的多,DB扣減的少,實際搶購賣出的少,換句話說就是出現了少賣的現象,

  • Q:會不會出現超賣現象?

    A: 不會,依賴于Redis單執行緒命令執行的保證,這里需要注意的是讀、寫命令不是一致,可以結合分布式鎖實作,也可以通過Lua腳本實作命令的原子性執行,

這里也是一個弱一致性的實作,業務場景我們保證不超賣即可,對于極端情況出現的庫存數量無效多扣減做戰略性放棄,一般情況下不會影響大多業務使用,如果非要吹毛求疵達到賬戶金額那種強一致性,思路也很簡單,可以借助定時任務輪詢對比快取與DB庫存數量進行校驗,這里還要考慮到其他在行流程如超市關單庫存恢復,仍然在行的秒殺活動等,保證資料處理不多加不多減,

3. 總結

3.1 分布式角色

  • 參與者
    可以通俗的認為是DB、RPC、MQ這些能夠提供事務能力的中間件或介面服務
  • 協調者
    維系分布式事務各個參與者分布式狀態的系統、中間件,如Zookeeper、業務系統

3.2 技術保證

  • 資料庫事務 資料庫如MYSQL提供了2PC、XA協議,依賴于WAL + Redo Log + 刷盤策略保證
  • MQ事務 提供了2PC協議,依賴于Ack機制+刷盤策略保證

3.2 強弱一致選擇

  • 強一致性
    強一致性確保的不是事務一定成功,而是事務參與者的子事務要么全成功,要么全失敗,保證子事務的最終一致,一般依賴于定時任務、補償機制、Double Check等方式進行事務狀態的校準和協調,一般設計和實作的復雜度大,參與者越多,流程越復雜,越難以維護,最終一致的延遲性和可靠性保證越難
  • 弱一致性
    弱一致性放棄了最終一致性的保證,通過最大努力實作而不保證最終的結果,這種場景減少和減低了開發和設計的復雜度

3.3 冪等&防重

  • 業務冪等通常會定義bizId代表全域唯一的業務標識,在MQ重發、重復消費、亂序,RPC重復呼叫等場景進行業務防重兼容處理,
  • 如賬戶余額的強一致防重處理,可以結合流水表唯一索引正逆向型別 + 業務ID進行攔截
  • 一般大多依賴于資料庫的唯一索引進行防重保證,如果擔心資料庫性能問題,可以前置快取攔截處理

3.4 盡早干預&補償一致

  • 盡早干預
    指的是代碼邏輯上盡早對串行處理的做個子事務進行回滾或逆向操作,這樣可以盡快結束分布式事務,而不需要等待相對更為延遲的定時任務或其他補償機制來驅動,這里可以使用旁路方法或不阻塞主方法放到MQ或異步執行緒中進行處理,比如秒殺下單發貨因為庫存不足或商品下架可以立刻進行發起關單退款的逆向流程
  • 補償一致
    補償機制一般可以通過定時任務、MQ重試來進行子事務驅動整個分布式事務的完結

5. 參考

《軟體架構設計:大型網站技術架構與業務架構融合之道》
用戶增長運營活動系統
電商大促秒殺活動系統
用戶中心認證系統

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/265659.html

標籤:其他

上一篇:AutoSAR配置視頻講解:Mcal配置

下一篇:Spring Cloud 學習筆記五:搭建微服務工程之Hystrix 的實時監控功能

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more