日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

借助Nacos高效配置與實踐Seata事務的TCC模式

來源: 責編: 時間:2024-02-01 12:45:10 213觀看
導讀實現TCC 模式TCC模式與AT模式非常相似,每階段都是獨立事務,不同的是TCC通過人工編碼來實現數據恢復。需要實現三個方法:Try:資源的檢測和預留;Confirm:完成資源操作業務;要求 Try 成功 Confirm 一定要能成功。Cancel:預留資源

實現

TCC 模式

TCC模式與AT模式非常相似,每階段都是獨立事務,不同的是TCC通過人工編碼來實現數據恢復。需要實現三個方法:NhI28資訊網——每日最新資訊28at.com

  • Try:資源的檢測和預留;
  • Confirm:完成資源操作業務;要求 Try 成功 Confirm 一定要能成功。
  • Cancel:預留資源釋放,可以理解為try的反向操作。

流程分析

圖片圖片NhI28資訊網——每日最新資訊28at.com

階段一(Try):檢查余額是否充足,如果充足則凍結金額增加30元,可用余額扣除30NhI28資訊網——每日最新資訊28at.com

圖片圖片NhI28資訊網——每日最新資訊28at.com

圖片圖片NhI28資訊網——每日最新資訊28at.com

此時,總金額 = 凍結金額 + 可用金額,數量依然是100不變,事務直接提交無需等待其它事務。NhI28資訊網——每日最新資訊28at.com

階段二(Confirm) :假如要提交,則凍結金額扣減30NhI28資訊網——每日最新資訊28at.com

圖片圖片NhI28資訊網——每日最新資訊28at.com

確認可以提交,不過之前可用金額已經扣減過了,這里只要清除凍結金額就好了,此時,總金額 = 凍結金額 + 可用金額 = 0 + 70 = 70NhI28資訊網——每日最新資訊28at.com

階段二(Cancel):如果要回滾,則凍結金額扣減30,可用余額增加30NhI28資訊網——每日最新資訊28at.com

圖片圖片NhI28資訊網——每日最新資訊28at.com

需要回滾,那么就要釋放凍結金額,恢復可用金額NhI28資訊網——每日最新資訊28at.com

Seata的TCC模型

圖片圖片NhI28資訊網——每日最新資訊28at.com

代碼樣例

配置和依賴參考之前《利用Nacos實現Seata事務模式(XA與AT)的快速配置與靈活切換》即可NhI28資訊網——每日最新資訊28at.com

bank3:NhI28資訊網——每日最新資訊28at.com

聲明TCC接口@LocalTCCpublic interface AccountInTcc {    @TwoPhaseBusinessAction(name = "prepareDeductMoney", commitMethod = "commitDeductMoney", rollbackMethod = "rollbackDeductMoney")    boolean prepareDeductMoney(BusinessActionContext businessActionContext,                               @BusinessActionContextParameter(paramName = "accountNo")String accountNo,                               @BusinessActionContextParameter(paramName = "amount")Double amount);    /**     * 提交扣款     * 二階段confirm確認方法、可以另命名,但要保證與commitMethod一致     */    boolean commitDeductMoney(BusinessActionContext businessActionContext);    /**     * 回滾扣款     * 二階段回滾方法,要保證與rollbackMethod一致     */    boolean rollbackDeductMoney(BusinessActionContext businessActionContext);}

具體實現:NhI28資訊網——每日最新資訊28at.com

@Componentpublic class AccountInTccImpl implements AccountInTcc {    @Autowired    private AccountInfoMapper accountInfoMapper;    @Transactional    @Override    public boolean prepareDeductMoney(BusinessActionContext businessActionContext, String accountNo, Double amount) {        String xid = businessActionContext.getXid();        // 冪等性判斷        if (TccActionResultWrap.hasPrepareResult(xid)) {            return true;        }        // 避免空懸掛,已經執行過回滾了就不能再預留資源        if (TccActionResultWrap.hasRollbackResult(xid) || TccActionResultWrap.hasCommitResult(xid)) {            return false;        }        // 預留資源        boolean result = accountInfoMapper.prepareDeductMoney(accountNo,amount) > 0;        // 記錄執行結果,以便回滾時判斷是否是空回滾        TccActionResultWrap.prepareSuccess(xid);        System.out.println("============prepare==============");        return result;    }    // 保證提交邏輯的原子性    @Transactional    @Override    public boolean commitDeductMoney(BusinessActionContext businessActionContext) {        String xid = businessActionContext.getXid();        // 冪等性判斷        if (TccActionResultWrap.hasCommitResult(xid)) {            return true;        }        Map<String, Object> actionContext = businessActionContext.getActionContext();        String accountNo = (String) actionContext.get("accountNo");        BigDecimal amount = (BigDecimal) actionContext.get("amount");        // 執行提交操作,扣除預留款        boolean result = accountInfoMapper.commitDeductMoney(accountNo,amount.doubleValue()) > 0;        // 清除預留結果        TccActionResultWrap.removePrepareResult(xid);        // 設置提交結果        TccActionResultWrap.commitSuccess(xid);        System.out.println("============commit==============");        return result;    }    @Transactional    @Override    public boolean rollbackDeductMoney(BusinessActionContext businessActionContext) {        String xid = businessActionContext.getXid();        // 冪等性判斷        if (TccActionResultWrap.hasRollbackResult(xid)) {            return true;        }        // 沒有預留資源結果,回滾不做任何處理;        if (!TccActionResultWrap.hasPrepareResult(xid)) {            // 設置回滾結果,防止空回滾            TccActionResultWrap.rollbackSuccess(xid);            return true;        }        // 執行回滾        Map<String, Object> actionContext = businessActionContext.getActionContext();        String accountNo = (String) actionContext.get("accountNo");        BigDecimal amount = (BigDecimal) actionContext.get("amount");        boolean result = accountInfoMapper.rollbackDeductMoney(accountNo,amount.doubleValue()) > 0;        // 清除預留結果        TccActionResultWrap.removePrepareResult(xid);        // 設置回滾結果        TccActionResultWrap.rollbackSuccess(xid);        System.out.println("============rollback==============");        return result;    }}

業務層:NhI28資訊網——每日最新資訊28at.com

@Autowired  private AccountInTcc accountInTcc;  @Override  public Boolean deductMoney(String accountNo, Double amount) {      return accountInTcc.prepareDeductMoney(null,accountNo,amount);  }

參數中的BusinessActionContext不需要開發人員自己傳遞,直接給null即可,Seata會自動處理。NhI28資訊網——每日最新資訊28at.com

mapper:NhI28資訊網——每日最新資訊28at.com

@Update("update account_info set account_balance = account_balance - #{amount}, frozen_money = frozen_money + #{amount} where account_no = #{accountNo} and account_balance >= #{amount}")    int prepareDeductMoney(@Param("accountNo") String accountNo, @Param("amount") Double amount);    @Update("update account_info set frozen_money = frozen_money - #{amount} where account_no = #{accountNo}")    int commitDeductMoney(@Param("accountNo") String accountNo, @Param("amount") Double amount);    @Update("update account_info set account_balance = account_balance + #{amount}, frozen_money = frozen_money - #{amount} where account_no = #{accountNo}")    int rollbackDeductMoney(@Param("accountNo") String accountNo, @Param("amount") Double amount);

bank4服務調用:NhI28資訊網——每日最新資訊28at.com

@GlobalTransactional    @Override    public Boolean addMoney(String accountNo, Double amount) {        String result = bank3Client.deduct(amount);        if("true".equalsIgnoreCase(result)){            Boolean flag = baseMapper.addMoney(accountNo,amount) > 0;            if(amount != 30 ) throw new RuntimeException("bank4 make exception amount != 30");            return flag;        }        return false;    }

TCC的優點:NhI28資訊網——每日最新資訊28at.com

  • 一階段完成直接提交事務,釋放數據庫資源,性能好
  • 相比AT模型,無需生成快照,無需使用全局鎖,性能最強
  • 不依賴數據庫事務,而是依賴補償操作,可以用于非事務型數據庫

TCC的缺點:NhI28資訊網——每日最新資訊28at.com

  • 有代碼侵入,需要人為編寫try、Confirm和Cancel接口,太麻煩
  • 軟狀態,事務是最終一致
  • 需要考慮Confirm和Cancel的失敗情況,做好冪等處理
  • 空回滾:當某分支事務的try階段阻塞時,可能導致全局事務超時而觸發二階段的cancel操作。在未執行try操作時先執行了cancel操作,這時cancel不能做回滾,就是空回滾
  • 業務懸掛:對于已經空回滾的業務,之前被阻塞的try操作恢復,繼續執行try,就永遠不可能confirm或cancel ,事務一直處于中間狀態,這就是業務懸掛。

圖片圖片NhI28資訊網——每日最新資訊28at.com

執行cancel操作時,應當判斷try是否已經執行,如果尚未執行,則應該空回滾。NhI28資訊網——每日最新資訊28at.com

執行try操作時,應當判斷cancel是否已經執行過了,如果已經執行,應當阻止空回滾后的try操作,避免懸掛。NhI28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-70394-0.html借助Nacos高效配置與實踐Seata事務的TCC模式

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: PHP 高性能的事件循環庫 Revolt

下一篇: Vue3問題:如何實現頁面引導提示?

標簽:
  • 熱門焦點
  • K60 Pro官方停產 第三方瞬間漲價

    雖然沒有官方宣布,但Redmi的一些高管也已經透露了,Redmi K60 Pro已經停產且不會補貨,這一切都是為了即將到來的K60 Ultra鋪路,屬于廠家的正常操作。但有意思的是該機在停產之后
  • JavaScript 混淆及反混淆代碼工具

    介紹在我們開始學習反混淆之前,我們首先要了解一下代碼混淆。如果不了解代碼是如何混淆的,我們可能無法成功對代碼進行反混淆,尤其是使用自定義混淆器對其進行混淆時。什么是混
  • 三言兩語說透設計模式的藝術-簡單工廠模式

    一、寫在前面工廠模式是最常見的一種創建型設計模式,通常說的工廠模式指的是工廠方法模式,是使用頻率最高的工廠模式。簡單工廠模式又稱為靜態工廠方法模式,不屬于GoF 23種設計
  • 分享六款相見恨晚的PPT模版網站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS網站旨在為全球Office用戶提供豐富的高品質原創PPT模板、實用文檔、數據圖表及個性化定制服務。優點:OfficePLUS是微軟官方網站,囊括PPT模板、Word模
  • 微信語音大揭秘:為什么禁止轉發?

    大家好,我是你們的小米。今天,我要和大家聊一個有趣的話題:為什么微信語音不可以轉發?這是一個我們經常在日常使用中遇到的問題,也是一個讓很多人好奇的問題。讓我們一起來揭開這
  • 自動化在DevOps中的力量:簡化軟件開發和交付

    自動化在DevOps中扮演著重要角色,它提升了DevOps的效能。通過自動化工具和方法,DevOps團隊可以實現以下目標:消除手動和重復性任務。簡化流程。在整個軟件開發生命周期中實現更
  • 共享單車的故事講到哪了?

    來源丨海克財經與共享充電寶相差不多,共享單車已很久沒有被國內熱點新聞關照到了。除了一再漲價和用戶直呼用不起了。近日多家媒體再發報道稱,成都、天津、鄭州等地多個共享單
  • “又被陳思誠騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國產懸疑電影,成了陳思誠的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠再度風頭無兩。你可以說陳思誠的
  • SN570 NVMe SSD固態硬盤 價格與性能兼具

    SN570 NVMe SSD固態硬盤是西部數據發布的最新一代WD Blue系列的固態硬盤,不僅閃存技術更為精進,性能也得到了進一步的躍升。WD Blue SN570 NVMe SSD的包裝外
Top 主站蜘蛛池模板: 温泉县| 维西| 靖安县| 秀山| 平凉市| 开远市| 镇雄县| 盐池县| 仲巴县| 蕉岭县| 浙江省| 新宁县| 黄浦区| 中西区| 浦东新区| 平果县| 永和县| 宿松县| 维西| 甘德县| 芷江| 铁力市| 重庆市| 类乌齐县| 哈密市| 益阳市| 临朐县| 鹿邑县| 连州市| 平原县| 邹平县| 体育| 临夏市| 图木舒克市| 钟山县| 翼城县| 崇仁县| 宣化县| 余庆县| 睢宁县| 无棣县|