• 152850

      文章

    • 1250

      評論

    • 6

      友鏈

    • 最近新加了換膚功能,大家多來逛逛吧~~~~
    • 喜歡這個網站的朋友可以加一下QQ群,我們一起交流技術。

    分布式事務之TCC事務

    TCC 事務介紹

    在08年的軟件開發2.0技術大會上,支付寶程立在PPT大規模SOA系統中的分布事務處理,提出TCC概念。 在網絡上搜索分布式事務相關的博客,基本都會提及這個PPT,目前很多分布式事務開源項目也都是基于TCC的思想實現。

    TCC 將事務提交分為 Try - Confirm - Cancel 3個操作。

    • Try:預留業務資源/數據效驗
    • Confirm:確認執行業務操作
    • Cancel:取消執行業務操作

    TCC事務處理流程和 2PC 二階段提交類似,不過 2PC通常都是在跨庫的DB層面,而TCC本質就是一個應用層面的2PC。


    TCC原理圖,圖片來自阿里公眾號文章

    TCC 優缺點

    TCC優點:讓應用自己定義數據庫操作的粒度,使得降低鎖沖突、提高吞吐量成為可能。

    TCC不足之處:

    • 對應用的侵入性強。業務邏輯的每個分支都需要實現try、confirm、cancel三個操作,應用侵入性較強,改造成本高。
    • 實現難度較大。需要按照網絡狀態、系統故障等不同的失敗原因實現不同的回滾策略。為了滿足一致性的要求,confirm和cancel接口必須實現冪等。

    TCC 事務應用場景

    我們通過用戶下單使用余額+紅包支付來看一下TCC事務的具體應用。

    假設用戶下單操作來自3個系統下單系統、資金賬戶系統、紅包賬戶系統,下單成功需要同時調用資金賬戶服務和紅包服務完成支付

    假設購買商品1000元,使用賬戶紅包200元,余額800元,確認支付。

    • Try操作
      tryX 下單系統創建待支付訂單
      tryY 凍結賬戶紅包200元
      tryZ 凍結資金賬戶800元

    • Confirm操作
      confirmX 訂單更新為支付成功
      confirmY 扣減賬戶紅包200元
      confirmZ 扣減資金賬戶800元

    • Cancel操作
      cancelX 訂單處理異常,資金紅包退回,訂單支付失敗
      cancelY 凍結紅包失敗,賬戶余額退回,訂單支付失敗
      cancelZ 凍結余額失敗,賬戶紅包退回,訂單支付失敗

    TCC 開源項目實戰 tcc-transaction

    tcc-transaction 是TCC型事務Java實現,tcc-transaction不和底層使用的rpc框架耦合,也就是使用doubbo,thrift,web service,http等都可以
    首先感謝開源作者無私奉獻,順手star、fork下。

    在 tcc-transaction 事例中有dubbo、http實現,在這里我們使用dubbo事例。

    事例的具體功能,其實就是上面介紹的 下單使用余額+紅包支付。

    tcc-transaction 事務管理器日志持久化支持多種方式

    引用官方1.2指南說明:tcc-transaction框架使用transactionRepository持久化事務日志??梢赃x擇FileSystemTransactionRepository、SpringJdbcTransactionRepository、RedisTransactionRepository或ZooKeeperTransactionRepository。

    我們這里演示使用SpringJdbcTransactionRepository,存儲到MySQL

    1. 項目準備

    假設本地環境MySQL、Zookeeper都已經準備完畢

    使用IDEA,將項目克隆到本地

    我們使用的實例為tcc-transaction-dubbo-sample

    • tcc-transaction-dubbo-capital 資金賬戶dubbo服務
    • tcc-transaction-dubbo-capital-api 資金賬戶dubbo接口定義
    • tcc-transaction-dubbo-order 下單系統
    • tcc-transaction-dubbo-redpacket 紅包賬戶dubbo服務
    • tcc-transaction-dubbo-redpacket-api 紅包賬戶dubbo接口定義

    執行數據庫腳本: tcc-transaction\tcc-transaction-tutorial-sample\src\dbscripts\create_db_cap.sql (資金賬戶)

    tcc-transaction\tcc-transaction-tutorial-sample\src\dbscripts\create_db_ord.sql (訂單庫)

    tcc-transaction\tcc-transaction-tutorial-sample\src\dbscripts\create_db_red.sql (紅包賬戶)

    tcc-transaction\tcc-transaction-tutorial-sample\src\dbscripts\create_db_tcc.sql (事務日志持久化)

    修改項目配置: Zookeeper 配置

    zookeeper.address=127.0.0.1:2181
    
    如果非默認配置,需要將tcc-transaction-dubbo-sample 下的模塊全部修改
    
    

    JDBC連接配置:

    jdbc.driverClassName=com.mysql.jdbc.Driver
    tcc.jdbc.url=jdbc:mysql://127.0.0.1:3306/TCC?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
    jdbc.username=root
    jdbc.password=
    
    如果非默認配置,需要將tcc-transaction-dubbo-sample,tcc-transaction-sample-domain 下項目模塊修改
    

    2. 項目發布

    實例目前都是使用的Tomcat發布,我們先部署Tomcat:

    服務全部啟動成功:


    3. 多種事務場景測試

    • 第一種情況:紅包賬戶凍結成功(try)、資金賬戶凍結成功(try),訂單操作異常(try)

    模擬異常代碼:


    購買結果:


    此時訂單支付失敗,紅包賬戶凍結金額、資金賬戶凍結金額全部退回。
    通過多種類似方式測試,例如:紅包賬戶凍結異常、資金賬戶凍結異常,都會調cancel,退回凍結資源。所以在try階段的任意一方異常,都會執行全局回滾。

    • 第二種情況:訂單處理成功(confirm),資金賬戶扣減成功(confirm),但紅包賬戶扣減失敗(confirm)

    模擬異常代碼,在紅包扣減 confirm 操作制造異常:


    購買結果:


    此時訂單為支付成功,但實際紅包金額還處在凍結狀態,事務管理器記錄訂單confirm操作未執行成功,系統會不斷重試調用訂單的confirm操作,直到紅包扣減成功。

    手動將紅包服務異常代碼去掉,重啟服務,等到下一次重試,紅包凍結金額被扣除成功。

    • 第三種情況: 資金賬戶凍結成功(try),紅包賬戶凍結成功(try),訂單處理失敗(confirm)

    模擬異常代碼,在訂單 confirm 操作制造異常:


    購買結果:


    此時訂單支付成功,但實際資金賬戶凍結金額、紅包凍結金額都還沒有扣除成功,事務管理器記錄訂單confirm操作未執行成功,系統會通過不斷重試訂單的confirm操作,直到資金賬戶和紅包賬戶扣減成功。

    手動將異常代碼去掉,重啟服務,等到下一次重試,紅包和資金賬戶凍結金額被扣除。

    • 第四種情況:在第一種情況下,訂單cancel操作處理失敗(cancel)

    模擬異常代碼,在第一種情況下基礎,在cancel操作上在制造異常:

    購買結果:


    此時訂單支付失敗,資金賬戶、紅包賬戶凍結成功,事務管理器記錄訂單cancel操作失敗,系統會不斷重試訂單的cancel操作,直到資金賬戶和紅包賬戶凍結金額退回賬戶。

    手動將異常代碼去掉,重啟服務,下一次重試cancel操作,資金賬戶和紅包賬戶凍結金額退回。

    總結: try 操作成功,進入 confirm 操作,只要 confirm 處理失?。ú还苁菂f調者掛了,還是參與者處理失敗或超時),系統通過不斷重試直到處理成功。 進入 cancel 操作也是一樣,只要 cancel 處理失敗,系統通過不斷重試直到處理成功。

    引用一段對話,具體說明TCC使用場景,以及和2PC對比

    問題

    1. 對于轉賬的cancel事務,相對簡單,只要把賬務沖負即可??梢话愕臉I務邏輯會涉及很多流程、單證等操作,尤其是歷史系統,應該很難改造成tcc結構的吧,不知道你們用tcc用在什么場景下?
    2. 我第一次是在支付寶架構師程立PPT中聽說tcc結構的,不知道你的實現跟阿里系的實現是什么關系,目前應用的規模大嗎?
    3. 我理解try程序完成后,立即提交try事務,不會有鎖事務競爭??蛇@個時候賬戶余額的狀態也被設置成了類似不可讀的狀態吧,依然不可以在其他業務中查詢賬戶余額,那么這種方案比2PC優勢具體在什么地方?

    回答

    1. 我的感覺TCC是比較適合具有較強一致性要求的場景,賬務系統就是這樣場景;應用TCC也有一定的開發成本,如果沒有強一致性要求,可以考慮其他補償型方案;
    2. 目前已應用在線上環境多個應用,主要就是應用賬務系統里使用;因為不是開源的,我沒有看過阿里的實現,部分借鑒了他們的思路;希望有機會能看看;
    3. 在Try結束后,賬戶余額會有部分資金凍結,其他業務不可以使用凍結資金;和2PC比較的話,理解下來有兩點:
    • 2PC是基于資源層(如數據庫),TCC是基于SOA服務
    • 2PC是是用全局事務,數據被lock的時間跨整個事務,直到全局事務結束;而TCC里每個對資源操作的是本地事務,數據被lock的時間短,可擴展性好

    其實目前阿里分布式事務解決方案--GTS(Gloabel Trasaction Service)正在公測中,詳情可以參考這篇公眾號文章:GTS來了!阿里微服務架構下的分布式事務解決方案

    參考資料


    695856371Web網頁設計師②群 | 喜歡本站的朋友可以收藏本站,或者加入我們大家一起來交流技術!

    自定義皮膚 主體內容背景
    打開支付寶掃碼付款購買視頻教程
    遇到問題聯系客服QQ:419400980
    注冊梁鐘霖個人博客
    图片区乱小说区电影区