如何用TCC實現分布式事務?

TCC事務介紹

TCC(Try-Confirm-Cancel)是除可靠消息隊列以外的另一種常見的分布式事務機制,它是由數據庫專家帕特 · 赫蘭德(Pat Helland)在2007年撰寫的論文《Life beyond Distributed Transactions: An Apostate’s Opinion》中提出的。正式以Try-Confirm-Cancel作為名稱的是Atomikos公司,其注冊了TCC商標。

Atomikos公司在商業版本事務管理器ExtremeTransactions中提供了TCC方案的實現,但是由于其是收費的,因此相應的很多的開源實現方案也就涌現出來,如:tcc-transactionByteTCChmilyspring-cloud-rest-tcc

上次我們分享的使用RocketMQ實現分布式事務,雖然它也能保證最終的結果是相對可靠的,過程也足夠簡單(相對于TCC來說),但可靠消息隊列的整個實現過程完全沒有任何隔離性可言。

如果業務需要隔離,我們通常就應該重點考慮TCC方案,它天生適合用于需要強隔離性的分布式事務中

在具體實現上,TCC的操作有點復雜,它是一種業務侵入性較強的事務方案,要求業務處理過程必須拆分為“預留業務資源”和“確認/釋放消費資源”兩個子過程。另外,你看名字也能看出來,TCC的實現過程分為了三個階段:

圖片

??Try:?嘗試執行階段,完成所有業務可執行性的檢查(保障一致性),并且預留好事務需要用到的所有業務資源(保障隔離性)。

  • Confirm:?確認執行階段,不進行任何業務檢查,直接使用Try階段準備的資源來完成業務處理。注意,Confirm階段可能會重復執行,因此需要滿足冪等性。

  • Cancel:?取消執行階段,釋放Try階段預留的業務資源。注意,Cancel階段也可能會重復執行,因此也需要滿足冪等性。

空回滾和業務懸掛問題

空回滾:當某分支事務的try階段阻塞時,可能導致全局事務超時而觸發二階段的cancel操作。在未執行try操作時先執行了cancel操作,這時cancel不能做回滾,就是空回滾

業務懸掛:對于已經空回滾的業務,如果以后繼續執行try,就永遠不可能confirm或cancel,這就是業務懸掛。應當阻止執行空回滾后的try操作,避免懸掛。

TCC與XA區別

之前分布式事務-兩階段、三階段提交介紹了二階段提交,TCC與XA兩階段提交有著異曲同工之妙。下面我們看下兩者的區別:

圖片

  • 執行階段上:

    • 階段1:?在XA中,各個RM準備提交各自的事務分支,事實上就是準備提交資源的更新操作(insert、delete、update等);而在TCC中,是主業務活動請求(try)各個從業務服務預留資源。

    • 階段2:?XA根據第一階段每個RM是否都prepare成功,判斷是要提交還是回滾。如果都prepare成功,那么就commit每個事務分支,反之則rollback每個事務分支。TCC中,如果在第一階段所有業務資源都預留成功,那么confirm各個從業務服務,否則取消(cancel)所有從業務服務的資源預留請求。

  • XA是資源層面的分布式事務,強一致性,在兩階段提交的整個過程中,一直會持有資源的鎖?XA事務中的兩階段提交內部過程是對開發者屏蔽的,JTA規范中,通過UserTransactioncommit方法來提交全局事務,這只是一次方法調用,其內部會委派給TransactionManager進行真正的兩階段提交,因此開發者從代碼層面是感知不到這個過程的。而事務管理器在兩階段提交過程中,從preparecommit/rollback過程中,資源實際上一直都是被加鎖的。如果有其他人需要更新這兩條記錄,那么就必須等待鎖釋放。

  • TCC是業務層面的分布式事務,最終一致性,不會一直持有資源的鎖?TCC中的兩階段提交并沒有對開發者完全屏蔽,也就是說從代碼層面,開發者是可以感受到兩階段提交的存在。如下單案例中:在第一階段,庫存中心需要提供try接口(庫存預留)。在第二階段,庫存需要提供confirm/cancel接口(確認庫存扣減/取消庫存預扣減)。開發者明顯的感知到了兩階段提交過程的存在。try、confirm/cancel在執行過程中,一般都會開啟各自的本地事務,來保證方法內部業務邏輯的ACID特性。其中:

    1. 1.?try過程的本地事務,是保證資源預留的業務邏輯的正確性。

    2. 2.?confirm/cancel執行的本地事務邏輯確認/取消預留資源,以保證最終一致性,也就是所謂的補償型事務(Compensation-Based Transactions)。

示例

用戶購買商品的業務邏輯。整個業務邏輯由3個微服務提供支持:資金服務、紅包服務、訂單服務。

紅包服務

public?interface?RedPacketTradeOrderService?{@EnableTccpublic?String?record(RedPacketTradeOrderDto?tradeOrderDto);
}

資金服務

public?interface?CapitalTradeOrderService?{@EnableTccpublic?String?record(CapitalTradeOrderDto?tradeOrderDto);
}

訂單服務

主要業務邏輯如下:

@Service
public?class?PaymentServiceImpl?{@AutowiredCapitalTradeOrderService?capitalTradeOrderService;@AutowiredRedPacketTradeOrderService?redPacketTradeOrderService;@AutowiredOrderRepository?orderRepository;@Compensable(confirmMethod?=?"confirmMakePayment",?cancelMethod?=?"cancelMakePayment",?asyncConfirm?=?false)public?void?makePayment(@UniqueIdentity?String?orderNo)?{System.out.println("order?try?make?payment?called.time?seq:"?+?DateFormatUtils.format(Calendar.getInstance(),?"yyyy-MM-dd?HH:mm:ss"));Order?order?=?orderRepository.findByMerchantOrderNo(orderNo);String?result?=?capitalTradeOrderService.record(buildCapitalTradeOrderDto(order));String?result2?=?redPacketTradeOrderService.record(buildRedPacketTradeOrderDto(order));}public?void?confirmMakePayment(String?orderNo)?{System.out.println("order?confirm?make?payment?called.?time?seq:"?+?DateFormatUtils.format(Calendar.getInstance(),?"yyyy-MM-dd?HH:mm:ss"));Order?foundOrder?=?orderRepository.findByMerchantOrderNo(orderNo);//check?if?the?trade?order?status?is?PAYING,?if?no,?means?another?call?confirmMakePayment?happened,?return?directly,?ensure?idempotency.if?(foundOrder?!=?null)?{foundOrder.confirm();orderRepository.update(foundOrder);}}public?void?cancelMakePayment(String?orderNo)?{System.out.println("order?cancel?make?payment?called.time?seq:"?+?DateFormatUtils.format(Calendar.getInstance(),?"yyyy-MM-dd?HH:mm:ss"));Order?foundOrder?=?orderRepository.findByMerchantOrderNo(orderNo);//check?if?the?trade?order?status?is?PAYING,?if?no,?means?another?call?cancelMakePayment?happened,?return?directly,?ensure?idempotency.if?(foundOrder?!=?null)?{foundOrder.cancelPayment();orderRepository.update(foundOrder);}}
}

相關資料

開源TCC實現方案

  • https://github.com/changmingxie/tcc-transaction

  • https://github.com/liuyangming/ByteTCC

  • https://github.com/dromara/hmily

  • https://github.com/prontera/spring-cloud-rest-tcc

Atomikos的官方TCC參考文檔

  • https://www.atomikos.com/downloads/articles/TransactionsForSOA-WhitePaper.pdf

  • https://www.atomikos.com/Main/DownloadPublications?article=TccForRestApi.pdf

  • Atomikos ExtremeTransactions Guide:atomikos 商業版本事務管理器ExtremeTransactions使用指南。

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

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

相關文章

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的體育賽事目標檢測系統(Python+PySide6界面+訓練代碼)

摘要:開發和研究體育賽事目標檢測系統對于增強體育分析和觀賞體驗至關重要。本篇博客詳細講述了如何運用深度學習技術構建一個體育賽事目標檢測系統,并提供了完整的實現代碼。系統基于先進的YOLOv8算法,對比了YOLOv7、YOLOv6、YOLOv5的性能&a…

【webrtc】p2p_transport_channel 中忽略Hyper-V

【win11】更改網絡適配器設置 刪掉了hype-v,這時候wsl2 打不開了,但是重啟后,還是存在hyper-v那么,讓webrtc自己不適用hyper-v的網絡Hyper-V 的全程:Hyper-V Virtual Ethernet Adapter https://github.com/SophistSolutions/Stroika/blob/2cd5e8bf4ee01cb5c423367b4df628f…

MFC 模態對話框退出機制的探究

一位讀者問了這樣一個問題: ” 如果我創建了一個可見的模態對話框,卻對用戶來說不可用。舉個例子,假設我在程序中的其他位置收到一個事件,并且我從事件中調用模態 CDialog 上的 DestroyWindow。我注意到 OnDestroy 是在 CDialog 上調用的,但在將 WM_QUIT 消息發送到模態對…

在MyBatis中自定義JsonTypeHandler

在MyBatis中使用自定義的JsonTypeHandler 在處理數據庫中的JSON字段時,我們經常需要將JSON字符串映射到Java對象,或者將Java對象序列化為JSON字符串以存儲在數據庫中。MyBatis作為一個流行的Java持久層框架,允許我們通過自定義類型處理器&am…

爬蟲入門到精通_實戰篇7(Requests+正則表達式爬取貓眼電影)_ 抓取單頁內容,正則表達式分析,保存至文件,開啟循環及多線程

1 目標 貓眼榜單TOP100:https://www.maoyan.com/board 2 流程框架 抓取單頁內容:利用requests請求目標站點,得到單個網頁HTML代碼,返回結果。正則表達式分析:根據HTML代碼分析得到電影名稱,主演,上映時間,評分,圖片…

跨域問題與解決方法

跨域問題與解決方法 同源策略 瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協議域名端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源。 同源策略限制以下幾種行為: Cookie、LocalStorage 和 IndexDB 無法讀取 DO…

C語言中的分支和循環語句:從入門到精通

分支和循環語句 1. 前言2. 預備知識2.1 getchar函數2.2 putchar函數2.3 計算數組的元素個數2.4 清屏2.5 程序的暫停2.6 字符串的比較 3. 結構化3.1 順序結構3.2 分支結構3.3 循環結構 4. 真假性5. 分支語句(選擇結構)5.1 if語句5.1.1 語法形式5.1.2 else…

Java網絡通信UDP

目錄 網絡通信基礎 UDP通信 服務器 1.想要使用UDP通信 要先打開DatagramSocket文件 端口號可以手動指定或系統隨機分配 2.阻塞等待接收客戶端數據;創建DatagramPacket接收客戶端傳來的數據 3.處理客戶端傳來的數據,并進行業務處理(這里…

MySQL 教程 2.4

MySQL UNION 操作符 本教程為大家介紹 MySQL UNION 操作符的語法和實例。 描述 MySQL UNION 操作符用于連接兩個以上的 SELECT 語句的結果組合到一個結果集合,并去除重復的行。 UNION 操作符必須由兩個或多個 SELECT 語句組成,每個 SELECT 語句的列數…

Python降維數據庫之umap使用詳解

概要 在數據科學和機器學習領域,數據通常是高維度的,而高維度數據不僅難以可視化,還會增加建模的復雜性。降維是一種處理高維數據的關鍵技術,而Python UMAP(Uniform Manifold Approximation and Projection)是一種強大的降維工具,它在保留數據結構的同時,將高維數據映…

uni-app引用外部js文件

全局引用 在App.vue文件中添加如下代碼 這樣在全局所有頁面中都可以直接使用該外部js中的函數 onLaunch: function() {var script document.createElement(script);script.src "https://www.test.com/api/testapi.js";document.body.appendChild(script); }, 單…

【IDEA+通義靈碼插件】實現屬于你的大模型編程助手

目錄 1.前言 2.下載安裝 3.解釋代碼 4.生成單元測試 5.生成注釋 6.智能補全 1.前言 大模型到底該以一種什么方式落地,從而嵌入我們的工作當中,助力我們工作效率的提升,其實最好的方式也許就是虛擬助手的方式,就像鋼鐵俠的&…

【OpenCV基礎(三)】Ubuntu系統下EasyPR環境配置

環境配置 1、資源下載2、環境配置2.1、1、將EasyPR壓縮包拷貝到Ubuntu 三種方法任選一種2.2、解壓得到EasyPR文件夾(文件夾一層進入后EasyPR資源內容)2.3、終端命令修改權限**chmod -R 777 ./ EasyPR**2.4、查找EasyPR/include/easypr/config.h,使用gedit方式打開2.…

uni-app app實現web-view H5圖片長按下載

問題和使用場景描述: uniapp app web-view中圖片無法長按保存,IOS下是正常的,但是Android下長按無反應 解決方案: 下載mui.min.js,放到項目中的static下(下載見最上面的壓縮包) 在static目錄下新建script.js mui.…

vue2本地開發環境正常,生產環境下this.$router.push({ name: ‘login‘ })不跳轉

如果在Vue.js 2中在本地開發環境下正常運行,但在生產環境下使用??this.$router.push({ name: login })??不起作用,可能有幾個原因需要檢查和解決: 路由配置問題: 確保你的路由配置正確,特別是確保在生產環境中,路由的配置和本地開發環境一致。檢查是否正確設置了name…

基于springboot+vue的智能學習平臺系統

博主主頁:貓頭鷹源碼 博主簡介:Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰,歡迎高校老師\講師\同行交流合作 ?主要內容:畢業設計(Javaweb項目|小程序|Pyt…

SAP PP學習筆記 - 豆知識07 - 如何查看BOM一覽

SAP標準提供了CS03,只能查詢單個的BOM,如果想查看一覽,只能自己寫SQVI 查詢。 有其他高招的童鞋,請賜教啊。 1,SQVI 工具 SAP MM學習筆記18- SQVI 工具_sap sqvi-CSDN博客 輸入查詢名,然后點擊 登錄 2&a…

#QT(DEMO2-登錄界面)

1.IDE:QTCreator 2.實驗:DEMO登錄 3.記錄 Line Edit輸入不換行 密碼框輸入如下設置: 運行效果 4.代碼

Vue.js+SpringBoot開發在線課程教學系統

目錄 一、摘要1.1 系統介紹1.2 項目錄屏 二、研究內容2.1 課程類型管理模塊2.2 課程管理模塊2.3 課時管理模塊2.4 課程交互模塊2.5 系統基礎模塊 三、系統設計3.1 用例設計3.2 數據庫設計 四、系統展示4.1 管理后臺4.2 用戶網頁 五、樣例代碼5.1 新增課程類型5.2 網站登錄5.3 課…

五、西瓜書——集成學習

1.個體與集成 集成學習通過將多個學習器進行結合,常可獲得比單一學習器顯著優越的泛化性能,這對“弱學習器”(weak learner)尤為明顯因此集成學習的很多理論研究都是針對弱學習器進行的而基學習器有時也被直接稱為弱學習器。 要獲得好的集成個體學習器應“好而不同”…