精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

分布式事務,阿里為什么鐘愛TCC

開發 架構 分布式
分布式事務的實現方式中,TCC是比較知名的模式。但是我一直不喜歡這種模式,原因是這種模式有很多問題要考慮。

 [[404481]]

本文轉載自微信公眾號「程序員jinjunzhu」,作者jinjunzhu 。轉載本文請聯系程序員jinjunzhu公眾號。

分布式事務的實現方式中,TCC是比較知名的模式。但是我一直不喜歡這種模式,原因是這種模式有很多問題要考慮。

之前寫過一篇文章說了TCC的很多缺點,后來我把文章刪了,原因是一位阿里大佬加我好友并指正了我的觀點。

太感謝了!

1 TCC概要

簡單來講,TCC模式就是將整個事務分成兩個階段來提交,try階段進行預留資源,如果所有分支都預留成功,則進入commit階段提交所有分支事務,否則執行cancel取消所有分支事務。

以電商系統為例,假如有訂單、庫存和賬戶3個服務,客戶購買一件商品,訂單服務增加訂單,庫存服務扣減庫存,賬戶服務扣減金額,這三個操作必須是原子性的,要么全部成功,要么全部失敗。

try階段

如下圖:

訂單服務增加一個訂單,庫存服務凍結訂單上的庫存,賬戶服務凍結訂單上的金額。

訂單、庫存和賬戶這三個服務作為整個分布式事務的分支事務,在try階段都是要提交本地事務的。上面庫存和賬戶說的凍結,就是說這個訂單對應的庫存和金額已經不能再被其他事務使用了,所以必須提交本地事務。

但這個提交并不是真正的提交全局事務,而是把資源轉到中間態,這個中間態需要在try方法的業務代碼中實現,比如賬戶扣除的金額可以先存放到一個中間賬戶。

如果try階段不提交本地事務會有什么問題呢?有可能其他事務在try階段發現用戶賬戶里面的金額還夠,但是commit的時候發現金額不夠了,commit階段扣款只能失敗,這時其他兩個分支事務提交成功而賬戶服務的分支事務提交失敗,最終數據就不一致了。

commit階段

如下圖:

commit階段,數據從中間態轉入終態,比如訂單金額從中間賬戶轉到最終賬戶。

cancel階段跟commit階段類似,比如訂單金額從中間賬戶退回到客戶賬戶。

2 問題代碼

下面這段代碼也可以理解為TCC,是在try階段hold住了connection,不提交分支事務,到commit階段再提交分支事務。代碼如下:我們以扣減賬戶為例,首先定義2個變量來hold住connection:

  1. private Map<String, Statement> statementMap = new ConcurrentHashMap<>(100); 
  2. private Map<String, Connection> connectionMap = new ConcurrentHashMap<>(100); 

try方法代碼如下:

  1. public boolean try(String xid, Long userId, BigDecimal payAmount) { 
  2.     LOGGER.info("decrease, xid:{}", xid); 
  3.     LOGGER.info("------->嘗試扣減賬戶開始account"); 
  4.  
  5.     try { 
  6.         //嘗試扣減賬戶金額,事務不提交 
  7.         Connection connection = hikariDataSource.getConnection(); 
  8.         connection.setAutoCommit(false); 
  9.         String sql = "UPDATE account SET balance = balance - ?,used = used + ? where user_id = ?"
  10.         PreparedStatement stmt = connection.prepareStatement(sql); 
  11.         stmt.setBigDecimal(1, payAmount); 
  12.         stmt.setBigDecimal(2, payAmount); 
  13.         stmt.setLong(3, userId); 
  14.         stmt.executeUpdate(); 
  15.         statementMap.put(xid, stmt); 
  16.         connectionMap.put(xid, connection); 
  17.     } catch (Exception e) { 
  18.         LOGGER.error("decrease parepare failure:", e); 
  19.         return false
  20.     } 
  21.  
  22.     LOGGER.info("------->嘗試扣減賬戶結束account"); 
  23.  
  24.     return true

commit方法代碼如下:

  1. public boolean commit(BusinessActionContext actionContext){ 
  2.     String xid = actionContext.getXid(); 
  3.     PreparedStatement statement = (PreparedStatement) statementMap.get(xid); 
  4.     Connection connection = connectionMap.get(xid); 
  5.     try { 
  6.         if (null != connection){ 
  7.             connection.commit(); 
  8.         } 
  9.     } catch (SQLException e) { 
  10.         LOGGER.error("扣減賬戶失敗:", e); 
  11.         return false
  12.     }finally { 
  13.         try { 
  14.             statementMap.remove(xid); 
  15.             connectionMap.remove(xid); 
  16.             if (null != statement){ 
  17.                 statement.close(); 
  18.             } 
  19.             if (null != connection){ 
  20.                 connection.close(); 
  21.             } 
  22.         } catch (SQLException e) { 
  23.             LOGGER.error("扣減賬戶提交事務后關閉連接池失敗:", e); 
  24.         } 
  25.     } 
  26.     return true

cancel方法代碼如下:

  1. public boolean rollback(BusinessActionContext actionContext){ 
  2.     String xid = actionContext.getXid(); 
  3.     PreparedStatement statement = (PreparedStatement) statementMap.get(xid); 
  4.     Connection connection = connectionMap.get(xid); 
  5.     try { 
  6.         connection.rollback(); 
  7.     } catch (SQLException e) { 
  8.         return false
  9.     }finally { 
  10.         try { 
  11.             if (null != statement){ 
  12.                 statement.close(); 
  13.             } 
  14.             if (null != connection){ 
  15.                 connection.close(); 
  16.             } 
  17.             statementMap.remove(xid); 
  18.             connectionMap.remove(xid); 
  19.         } catch (SQLException e) { 
  20.             LOGGER.error("扣減賬戶回滾事務后關閉連接池失敗:", e); 
  21.         } 
  22.     } 
  23.     return true

這段代碼是問題代碼,不能用,不能用,不能用

這個代碼存在兩個問題:

2.1 阻塞等待

如果當前事務不提交,比如賬戶服務,那就相當于是鎖定了資源,后面的事務只能等待資源釋放。

2.2 服務集群

以訂單服務為例,假如訂單服務是一個3個機器的集群,如下圖:

協調節點使用注冊中心客戶端來調用訂單服務,如果try請求發送到了訂單服務1,而commit請求發送到了訂單服務2,那訂單服務2上的connectionMap里不會有xid=123這個connection,只能提交失敗。

3 TCC存在的問題

上面的問題代碼就是給大家一個思路,如果真要hold住connection,也算是實現了TCC的思想,但是在系統中,我們是不可能這樣做的,所以把它叫做問題代碼。

3.1 空回滾

如下圖,訂單服務1節點故障,如果不考慮重試,try方法失敗:

try雖然失敗了,但是全局事務已經開啟,框架必須要把這個全局事務推向結束狀態,這就不得不調用訂單服務cancel方法進行回滾,結果訂單服務空跑了一次cancel方法。

解決這個問題,可以記錄一張事務控制表,保存全局事務xid和分支事務branchId,try階段會插入一條記錄,表示try階段執行了。cancel方法讀取該記錄,如果記錄存在,正常回滾;如果該記錄不存在,那就是空回滾。

3.2 冪等

冪等是指在commit/cancel階段,因為TC沒有收到分支事務的響應,需要進行重試,這就要分支事務支持冪等。以訂單服務為例。如下圖:

要支持冪等,可以記錄一張事務控制表,保存全局事務xid和分支事務branchId,以及分支事務狀態,在第二階段commit/cancel之前先檢查分支事務狀態是否已經是終態,如果不是,再執行第二階段的邏輯。

3.3 懸掛

懸掛是指事務的cancel方法比try方法先執行。上面講了seata的使用過程中會發生空回滾,如果發生了空回滾,執行了cancel方法后全局事務結束了,但是因為網絡問題,訂單服務又收到了try請求,執行try方法后預留資源成功,這些資源最終不能釋放了。

解決這個問題的方法就是在cancel方法中記錄xid對應的分支事務回滾記錄,try階段執行的時候先判斷分支事務是否已經回滾,如果存在回滾記錄,則直接退出。

3.4 業務代碼侵入

TCC的try/commit/cancel,對業務代碼都有侵入,而且每個方法都是一個本地事務。再加上需要考慮冪等、空回滾、懸掛等,代碼侵入會更高。

4.TCC優勢

這里以seata實現的四種模式來比較,包括XA、SAGA、TCC、AT。

效率

使用TCC模式時,在try階段就提交了本地事務,并不會鎖定資源,所以沒有其他額外的性能開銷。相比之下,來看其他幾種模式:

  • AT模式,需要記錄undolog,性能損耗很大。
  • XA模式,執行xa start | sql | xa end之后,執行commit/rollback之前,會鎖定資源,后面的事務需要等待。

saga模式

更適合長流程的業務場景。

5.性能優化

參考[1]

5.1 異步提交

優化思路是try階段成功后,不立即執行confirm/cancel階段,而是等系統空閑的時候異步執行。如下圖:

這樣在try階段結束后,就認為全局事務結束了,可以定時(比如10分鐘)來異步執行第二階段,性能大幅提升。

當然,帶來的一點問題就是如果全局事務回滾,會有短暫的數據不一致。比如扣款的場景,定時10分鐘執行一次異步任務,如果第二階段是cancel,那客戶會在這10分鐘內不能使用這筆金額。

這個異步執行的時間也可以根據業務來決定,比如不需要及時從中間賬戶轉移到最終賬戶的場景可以設置更長。

5.2 同庫模式

首先回顧一下TCC中各個角色:

  • TM管理全局事務,包括開啟全局事務,提交/回滾全局事務
  • RM管理分支事務
  • TC管理全局事務和分支事務的狀態

先看一下優化之前的通信模型,如下圖:

在優化之前,TM開啟全局事務時,RM需要向TC發送RPC消息進行注冊,TC保存分支事務的狀態。TM請求提交或回滾時,TC需要向RM發送RPC消息進行提交或回滾。這樣包含兩個個分支事務的分布式事務中,TC和RM之間有四次RPC。

優化之后的模型如下圖:

TM開啟全局事務時,不再需要向TC注冊分支事務,而是把分支事務狀態保存在了本地。TM向TC發送提交或回滾消息時,TC保存全局事務的狀態。而RM則啟動異步線程檢測本地記錄的未提交分支事務,向TC發送RPC消息獲取整體事務狀態,以決定是提交還是回滾本地事務。可見,優化后的模型,RPC次數減少了50%,性能大幅提升。

6.總結

TCC的問題確實不少,但是除了侵入業務代碼這一個問題,其他問題都有對應的解決方案。

阿里針對TCC做了一些優化,包括第二階段異步提交和同庫模式,性能提升很明顯。

 

責任編輯:武曉燕 來源: 程序員jinjunzhu
相關推薦

2022-01-12 10:02:02

TCC模式 Seata

2025-04-30 10:44:02

2024-10-09 14:14:07

2024-06-12 09:06:48

2025-05-07 00:10:00

分布式事務TCC模式

2021-11-05 07:18:15

分布式事務業務

2024-06-28 09:07:19

2024-12-09 09:35:00

2022-06-27 08:21:05

Seata分布式事務微服務

2018-11-23 09:25:00

TCC分布式事務

2022-07-20 06:55:10

TCC分布式事務微服務

2015-11-05 17:41:25

NoSQL分布式事務事務架構

2022-11-24 17:34:04

TCC分布式

2022-06-21 08:27:22

Seata分布式事務

2017-07-26 15:08:05

大數據分布式事務

2019-10-10 09:16:34

Zookeeper架構分布式

2019-01-11 18:22:07

阿里巴巴技術開源

2009-06-19 15:28:31

JDBC分布式事務

2021-09-29 09:07:37

分布式架構系統

2009-09-18 15:10:13

分布式事務LINQ TO SQL
點贊
收藏

51CTO技術棧公眾號

日韩中文字幕三区| 久久久久久久久久久久久久久久av | 国产精品久久久久无码av色戒| 性欧美xxx69hd高清| 国产清纯在线一区二区www| 成人免费观看网址| 日韩精品一区二区不卡| 精品国产欧美日韩| 日韩精品自拍偷拍| 92看片淫黄大片一级| 老司机免费在线视频| 不卡视频一二三四| 国产美女搞久久| 日本三级理论片| 日韩中文字幕高清在线观看| 亚洲白虎美女被爆操| 一区二区三区免费播放| 女同视频在线观看| 国产精品欧美一级免费| 精品国产二区在线| 国产精品久久久久久无人区| 99精品视频免费观看| 久久久国产视频91| 国产免费看av| 都市激情久久| 欧美群妇大交群的观看方式| 美女日批免费视频| 影音先锋男人资源在线| 国产欧美1区2区3区| 好吊妞www.84com只有这里才有精品| japanese国产在线观看| 亚洲国产二区| 久久亚洲电影天堂| 污污视频网站在线免费观看| 图片婷婷一区| 精品不卡在线视频| 免费高清视频在线观看| 欧美日韩国产网站| 午夜视频一区在线观看| 久久天天东北熟女毛茸茸| 电影在线高清| 久久久国际精品| 国产精品国产三级欧美二区| 国产精品熟女久久久久久| 日韩成人一级片| 日本午夜在线亚洲.国产| 欧美成人aaaaⅴ片在线看| 欧美激情无毛| 欧美美女操人视频| 国产精品久久久久久久精| 久久精品不卡| 国产视频欧美视频| 成人性生活免费看| 国偷自产av一区二区三区| 日韩欧美国产电影| 肉丝美足丝袜一区二区三区四| 91麻豆精品国产综合久久久 | 57pao国产成人免费| 日本在线小视频| 亚洲人妖在线| 97视频在线播放| 国产情侣在线视频| 亚洲美女色禁图| 欧美亚洲视频在线看网址| 91精品国产乱码久久久张津瑜| 亚洲成人原创| 欧美一区第一页| 精品无码一区二区三区的天堂| 日韩中文字幕91| 国产噜噜噜噜久久久久久久久| 欧美成人精品网站| 久久福利资源站| 成人激情av在线| 国产suv一区二区| 丁香桃色午夜亚洲一区二区三区| 国内一区在线| 国产一级在线| 国产精品热久久久久夜色精品三区| 亚洲国产精品综合| 黄网站视频在线观看| 一区二区免费在线播放| 国产精品999视频| 三级成人黄色影院| 欧美日本一区二区在线观看| 欧美性猛交乱大交| 欧美福利在线播放网址导航| 在线播放国产精品| 日本青青草视频| 亚洲一区二区三区高清| 国产精品免费久久久| 国产色视频在线| 99久久国产综合精品女不卡| 日韩成人在线资源| av网址在线播放| 欧美午夜激情视频| 中文字幕亚洲乱码| 欧美大片网址| 久久精品国产欧美亚洲人人爽| 国产精品16p| 免费一区二区视频| av一本久道久久波多野结衣| 美女毛片在线看| 亚洲精品欧美二区三区中文字幕| 国产一区二区三区小说| 欧美色网在线| 精品动漫一区二区三区在线观看| 日本人亚洲人jjzzjjz| 亚洲午夜一区| 国产精品青青在线观看爽香蕉| 好吊色一区二区| 日本一区二区三区免费乱视频 | 日韩av片在线| 亚洲二区精品| 成人福利视频网| 欧美偷拍视频| 亚洲综合视频在线观看| 欧美日韩亚洲自拍| 麻豆一区二区| 插插插亚洲综合网| 久久久999久久久| 成人高清视频在线| 好吊色这里只有精品| 美女福利一区二区| 亚洲成人精品视频| 一级黄色片日本| 久久精品在线| 精品综合在线| 黑森林国产精品av| 欧美成人性战久久| 婷婷久久综合网| 美女脱光内衣内裤视频久久网站 | 国产日韩在线免费| 好男人免费精品视频| 午夜伊人狠狠久久| 中国特级黄色片| 中文无码久久精品| 成人两性免费视频| 免费观看在线午夜影视| 欧美日韩日日骚| 国产美女免费网站| 玖玖在线精品| 欧美一区免费视频| www.com.cn成人| 精品无人国产偷自产在线| 国产亚洲色婷婷久久99精品| 国产成人精品一区二| 福利在线小视频| 国内不卡的一区二区三区中文字幕 | 国模大尺度视频| 午夜日本精品| 成人在线观看av| 日本乱理伦在线| 欧美不卡一区二区| 久草视频中文在线| 国产成人综合网| 国产精品88久久久久久妇女| 欧美三级一区| 欧美黑人性猛交| 天堂在线资源8| 欧美色播在线播放| 国产jjizz一区二区三区视频| 丝袜诱惑亚洲看片| 午夜精品一区二区三区在线观看| 欧美啪啪网站| 久久久精品久久久久| 国产夫妻在线观看| 亚洲国产精品久久不卡毛片| 三级电影在线看| 日韩和欧美一区二区三区| 亚洲成色www久久网站| 国产91亚洲精品久久久| 久久天堂电影网| 免费看国产片在线观看| 精品美女久久久久久免费| 成人免费av片| 美日韩一区二区三区| 视色,视色影院,视色影库,视色网| 亚洲专区**| 欧美亚洲成人xxx| 137大胆人体在线观看| 91精品国产高清一区二区三区蜜臀 | 性生活在线视频| 亚洲裸体俱乐部裸体舞表演av| 麻豆av一区| 欧美日韩破处视频| 欧美激情视频给我| 国产在线一在线二| 欧美剧情片在线观看| 伊人365影院| 欧美韩国日本一区| 国产精品99久久久精品无码| 久久久蜜桃一区二区人| 伊人婷婷久久| 亚洲精品亚洲人成在线观看| 91丨九色丨国产在线| 密臀av在线播放| 日韩视频免费大全中文字幕| 天天干天天爽天天操| 欧美日韩免费一区二区三区 | 国产原创精品| 99精品在免费线偷拍| 久久久久久久国产精品| 成人在线免费观看| 欧美精品一区二区蜜臀亚洲| 最近中文字幕免费在线观看| 亚洲成人黄色影院| 永久免费未视频| 久久久久久97三级| 久久久精品人妻一区二区三区| 日韩中文字幕一区二区三区| 亚洲精品久久久久久久蜜桃臀| 欧美午夜精彩| 久久亚洲免费| 亚洲高清在线一区| 国产精品视频在线播放| 涩涩视频在线| 欧美国产日韩二区| 国产精品扒开做爽爽爽的视频| 亚洲精品永久免费精品| 亚洲不卡免费视频| 欧美日韩一区二区三区视频| 天堂中文在线网| 亚洲va中文字幕| 91成人福利视频| 国产精品大尺度| 最近中文字幕免费| 99精品视频在线观看| 亚洲成年人在线观看| 极品美女销魂一区二区三区 | 高清欧美日韩| 青青草成人在线| а√在线中文在线新版| 欧美高清视频在线| 国产乱色在线观看| 久久精品国产一区| 男人资源在线播放| 中文字幕自拍vr一区二区三区| 可以在线观看的av网站| 亚洲精品自在久久| 天堂在线一二区| 亚洲精品99久久久久| 日韩一卡二卡在线| 亚洲福利精品在线| 欧美自拍第一页| 亚洲国产97在线精品一区| 亚洲精品911| 精品国产一区久久| 国产 日韩 欧美 综合| 日韩免费性生活视频播放| 精品国产av一区二区三区| 日韩午夜av电影| 亚洲精品综合久久| 精品成人一区二区| 四虎影视2018在线播放alocalhost| 亚洲精品乱码久久久久久金桔影视| 免费看av毛片| 国产视频精品xxxx| 国产女主播在线直播| 在线精品视频视频中文字幕| h网站视频在线观看| 色偷偷av亚洲男人的天堂| 麻豆网站在线免费观看| 久久精品福利视频| 麻豆视频网站在线观看| 久久电影一区二区| 欧美黑人猛交| 国模视频一区二区| 免费观看一级欧美片| 国产精品扒开腿做爽爽爽的视频| 国产成人免费| 亚洲最大的av网站| 国产精品国产| 欧美人与性禽动交精品| 欧美亚洲高清| 黄色一级视频播放| 亚洲精品系列| 欧美日韩在线视频一区二区三区| 欧美亚洲一区| 中文字幕第17页| 粉嫩av亚洲一区二区图片| 噜噜噜在线视频| 成人欧美一区二区三区在线播放| 欧美成人三级视频| 精品女同一区二区三区在线播放| 中文字幕+乱码+中文乱码91| 日韩三级精品电影久久久| 天天操天天干天天舔| 在线一区二区日韩| 激情av在线| 国产成人精品久久久| 日韩一区二区三区色| 欧美日韩精品免费观看| 亚洲澳门在线| 欧美亚洲另类色图| 国产专区综合网| 国产精品一级黄片| 成人免费在线观看入口| 日韩三级视频在线| 欧美肥妇毛茸茸| 日本不卡视频一区二区| 久久精品男人天堂| 欧美xxxx做受欧美护士| 不卡一卡2卡3卡4卡精品在| 超碰成人久久| 久色视频在线播放| 国产精品一区二区三区网站| 在线免费观看视频| 午夜精品福利在线| 国产乱码久久久久| 亚洲欧美国产精品专区久久| 日本高清在线观看| 国产欧美婷婷中文| 校花撩起jk露出白色内裤国产精品| 免费成人进口网站| 日本不卡一区二区三区| 精品国产人妻一区二区三区| 综合中文字幕亚洲| 国产黄色免费视频| 亚洲黄页视频免费观看| av在线免费播放| 国产日韩欧美在线观看| 国产精品片aa在线观看| 欧美啪啪免费视频| 粉嫩嫩av羞羞动漫久久久| 污污的视频在线免费观看| 在线亚洲一区二区| 嫩草研究院在线观看| 午夜精品久久久99热福利| 日韩成人久久| 黄色网zhan| 国产在线国偷精品产拍免费yy| 久久日免费视频| 91高清在线观看| 黄色免费在线播放| 日本亚洲欧洲色| 蜜桃成人av| 成人免费观看毛片| 久久久亚洲精品一区二区三区| 久草国产精品视频| 亚洲精品在线免费观看视频| 污污的网站在线看| 91中文字精品一区二区| 一区二区中文字| 亚洲妇女无套内射精| 亚洲综合激情网| 亚洲精品久久久蜜桃动漫| 欧美日韩国产成人在线| 天堂精品在线视频| 国产黄色激情视频| 国产不卡在线一区| 国产在线观看你懂的| 日本一级免费视频| 日韩三级久久久| 日本精品在线播放| 亚洲精品av在线| 日本视频在线观看| 国产精品日韩在线观看| 极品美女一区二区三区| 欧美午夜性生活| 国产精品视频观看| 91激情在线观看| 欧美另类极品videosbest最新版本 | a级片在线播放| 欧美另类极品videosbest最新版本 | 三级男人添奶爽爽爽视频 | 久久国产精品影视| 日韩一区网站| 国产精品久久久久9999爆乳| 99久久婷婷国产综合精品电影| 欧美在线观看不卡| 中文字幕久久亚洲| 精品国产一区二区三区2021| 国产精品第157页| av成人老司机| 国产真人无遮挡作爱免费视频| 最好看的2019年中文视频| 高清精品久久| 尤物av无码色av无码| 国产日韩欧美一区二区三区综合| 中文字幕在线观看1| 欧美裸身视频免费观看| 亚洲人成网77777色在线播放| 免费涩涩18网站入口| 一区二区三区不卡视频| 亚洲欧美一区二区三| 国产精品一区二区三区久久| 欧美激情一级片一区二区| 成年人在线观看av| 91精品在线免费观看| 黄色在线观看视频网站| 欧美重口乱码一区二区| 国产激情视频一区二区三区欧美| av资源免费观看| 久久天天躁狠狠躁夜夜躁| 久久综合另类图片小说| mm131亚洲精品| 偷拍与自拍一区| 黄色一级片在线观看| 欧美不卡在线一区二区三区| 国产精品主播直播|