### TCC模型(補償事務)
TCC(Try-Confirm-Cancel)分布式事務模型相對于 XA 等傳統模型,其特征在于它不依賴資源管理器(RM)對分布式事務的支持,而是通過對業務邏輯的分解來實現分布式事務。
TCC 模型認為對于業務系統中一個特定的業務邏輯,其對外提供服務時,必須接受一些不確定性,即對業務邏輯初步操作的調用僅是一個臨時性操作,調用它的主業務服務保留了后續的取消權。如果主業務服務認為全局事務應該回滾,它會要求取消之前的臨時性操作,這就對應從業務服務的取消操作。而當主業務服務認為全局事務應該提交時,它會放棄之前臨時性操作的取消權,這對應從業務服務的確認操作。每一個初步操作,最終都會被確認或取消
**TCC 分布式事務模型需要業務系統提供三段業務邏輯:**
1. 初步操作 Try:完成所有業務檢查,預留必須的業務資源。
2. 確認操作 Confirm:真正執行的業務邏輯,不作任何業務檢查,只使用 Try 階段預留的業務資源。因此,只要 Try 操作成功,Confirm 必須能成功。另外,Confirm 操作需滿足冪等性,保證一筆分布式事務有且只能成功一次。
3. 取消操作 Cancel:釋放 Try 階段預留的業務資源。同樣的,Cancel 操作也需要滿足冪等性

### TCC 分布式事務模型包括三部分:
1.主業務服務:主業務服務為整個業務活動的發起方,服務的編排者,負責發起并完成整個業務活動。
2.從業務服務:從業務服務是整個業務活動的參與方,負責提供 TCC 業務操作,實現初步操作(Try)、確認操作(Confirm)、取消操作(Cancel)三個接口,供主業務服務調用。
3.業務活動管理器:業務活動管理器管理控制整個業務活動,包括記錄維護TCC 全局事務的事務狀態和每個從業務服務的子事務狀態,并在業務活動提交時調用所有從業務服務的Confirm 操作,在業務活動取消時調用所有從業務服務的Cancel操作
**TCC 分布式事務流程如下:**
1. 主業務服務首先開啟本地事務;
2. 主業務服務向業務活動管理器申請啟動分布式事務主業務活動;
3. 然后針對要調用的從業務服務,主業務活動先向業務活動管理器注冊從業務活動,然后調用從業務服務的 Try 接口;
4. 當所有從業務服務的 Try 接口調用成功,主業務服務提交本地事務;若調用失敗,主業務服務回滾本地事務;
5. 若主業務服務提交本地事務,則 TCC 模型分別調用所有從業務服務的 Confirm 接口;若主業務服務回滾本地事務,則分別調用 Cancel 接口;
6. 所有從業務服務的 Confirm 或 Cancel 操作完成后,全局事務結束
#### 原子性
TCC 模型也使用 2PC 原子提交協議來保證事務原子性。Try 操作對應 2PC 的一階段準備(Prepare);Confirm 對應 2PC 的二階段提交(Commit),Cancel 對應 2PC 的二階段回滾(Rollback),可以說 TCC 就是應用層的 2PC。
#### 隔離性
TCC 分布式事務模型僅提供兩階段原子提交協議,保證分布式事務原子性。事務的隔離交給業務邏輯來實現。
隔離的本質是控制并發,防止并發事務操作相同資源而引起的結果錯亂。
舉個例子,比如金融行業里管理用戶資金,當用戶發起交易時,一般會先檢查用戶資金,如果資金充足,則扣除相應交易金額,增加賣家資金,完成交易。如果沒有事務隔離,用戶同時發起兩筆交易,兩筆交易的檢查都認為資金充足,實際上卻只夠支付一筆交易,結果兩筆交易都支付成功,導致資損。
可以發現,并發控制是業務邏輯執行正確的保證,但是像兩階段鎖這樣的并發訪問控制技術要求一直持有數據庫資源鎖直到整個事務執行結束,特別是在分布式事務架構下,要求持有鎖到分布式事務第二階段執行結束,也就是說,分布式事務會加長資源鎖的持有時間,導致并發性能進一步下降。
因此,TCC 模型的隔離性思想就是通過業務的改造,在第一階段結束之后,從底層數據庫資源層面的加鎖過渡為上層業務層面的加鎖,從而釋放底層數據庫鎖資源,放寬分布式事務鎖協議,提高業務并發性能。
還是以上面的例子舉例:
1.第一階段:檢查用戶資金,如果資金充足,凍結用戶本次交易資金,這筆資金被業務隔離,不允許除本事務之外的其它并發事務動用。
2.第二階段:扣除第一階段預凍結的用戶資金,增加賣家資金,完成交易。 采用業務加鎖的方式,隔離用戶凍結資金,在第一階段結束后直接釋放底層資源鎖,該用戶和賣家的其他交易都可以立刻并發執行,而不用等到整個分布式事務結束,可以獲得更高的并發交易能力。
#### 一致性
再來看看 TCC 分布式事務模型下的一致性實現。與 XA 協議實現一致性第一層語義類似,通過原子性保證事務的原子提交、業務隔離性控制事務的并發訪問,實現分布式事務的一致性狀態轉變。
至于第二層語義:事務的中間狀態不能被觀察到。我們來看看,在 SOA 分布式應用環境下是否是必須的。
還是以賬務服務舉例。轉賬業務(用戶 A ? 用戶 B),由交易服務和賬務服務組成分布式事務,交易服務作為主業務服務,賬務服務作為從業務服務,賬務服務的 Try 操作預凍結用戶 A 的資金;Commit 操作扣除用戶 A 的預凍結資金,增加用戶 B 的可用資金;Cancel 操作解凍用戶 A 的預凍結資金。
當賬務服務執行完 Try 階段后,交易主業務就可以 Commit 了,然后由 TCC 框架調用賬務的 Commit 階段。在賬務 Commit 階段還沒執行結束的時候,用戶 A 可以查詢到自己的余額已扣除,但是,此時用戶 B 的可用資金還沒增加。
從系統的角度來看,確實有問題與不確定性。在第一階段執行結束到第二階段執行結束之間,有一段時間的延時,在這段時間內,看似任何用戶都不享有這筆資產。
但是,從用戶的角度來考慮這個問題的話,這個時間間隔可能就無所謂或者根本就不存在。特別是當這個時間間隔僅僅是幾秒鐘,對于具體溝通資產轉移的用戶來講,這個過程是隱蔽的或確實可以接受的,且保證了結果的最終一致性。
當然,對于這樣的系統,如果確實需要查看系統的某個一致性狀態,可以采用額外的方法實現。
一般來講,服務之間的一致性比服務內部的一致性要更加容易弱化,這也是為什么 XA 等直接在資源層面上實現通用分布式事務的模型會注重一致性的保證,而當上升到服務層面,服務與服務之間已經實現了功能的劃分,邏輯的解耦,也就更容易弱化一致性,這就是 SOA 架構下 BASE 理論的最終一致性思想。
BASE 理論是指 BA(Basic Availability,基本業務可用性);S(Soft state,柔性狀態);E(Eventual consistency,最終一致性)。該理論認為為了可用性、性能與降級服務的需要,可以適當降低一點一致性的要求,即“基本可用,最終一致”。
業內通常把嚴格遵循 ACID 的事務稱為剛性事務;而基于 BASE 思想實現的事務稱為柔性事務。柔性事務并不是完全放棄了 ACID,僅僅是放寬了一致性要求:事務完成后的一致性嚴格遵循,事務中的一致性可適當放寬;
- 概述
- CAP理論
- BASE理論
- ACID
- 分布式系統相關技術
- 主流數據庫連接池
- 基礎
- 系統單點
- 負載均衡
- HTTP重定向負載均衡
- DNS域名解析負載均衡
- 反向代理負載均衡
- IP負載均衡
- 數據鏈路層負載均衡
- 負載均衡算法
- 輪詢法(Round Robin)
- 加權輪詢(Weight Round Robin)
- 隨機算法(Random)
- 源地址Hash算法
- 加權隨機法(Weight Random)
- 最小連接數法(Least Connections)
- 接入層負載均衡
- 軟件架構
- 性能
- 性能測試指標
- 響應時間
- 并發數
- 吞吐量
- 性能計數器
- 性能測試方法
- 性能測試報告
- 性能優化
- Web前端性能優化
- 應用服務器性能優化
- 可用性
- 服務降級
- 伸縮性
- 擴展性
- 事件驅動架構
- 安全性
- 信息加密技術
- 分布式系統概述
- 自動化
- 分布式唯一ID
- 冪等設計
- 分布式鎖
- 腦裂
- 一致性原理
- Paxos
- Zab
- Raft
- 分布式遠程服務調用
- RMI
- Spring RMI
- WebService
- SOA服務架構
- 微服務架構
- 微服務的九大特性
- 服務注冊和發現
- 解決方案及組件
- 分布式網關
- 注冊中心
- Zookeeper
- ZNode
- Watch接口
- 持久節點-配置中心實現原理
- 臨時節點-注冊中心
- Zookeeper選舉
- Zookeeper角色
- ZooKeeper工作原理
- 選主流程
- 同步流程
- Leader工作流程
- Follower工作流程
- 常見限流算法
- 計數器算法
- 漏桶算法
- 令牌桶算法
- 滑動窗口
- 計數器&滑動窗口
- 斷路器
- 大流量高并發高可用
- 高可用
- 高并發/大流量
- 分布式緩存系統
- 基本概念
- 緩存命中率
- 緩存最大元素
- 緩存回收策略
- 回收算法
- 緩存穿透與緩存雪崩
- CDN緩存
- 緩存分類
- memcached
- 客戶端路由原理
- 內存管理機制
- Redis
- Redis數據模型
- redisObject/Redis type/Redis encoding
- 命令的類型檢查和多態
- skiplist跳躍表
- 為什么使用跳躍表
- redis-內存管理機制
- Redis淘汰策略
- Redis持久化策略
- Redis并發競爭
- redis主從復制
- Redis集群實現方案
- Redis Cluster
- redis事務
- Redis-Sentinel
- Redis適用場景
- Redis客戶端
- redis rehash原理
- dict數據結構
- 觸發rehash的條件
- 漸進式rehash
- 漸進式rehash過程
- Redis多線程版本
- 緩存實際應用
- 堆緩存-Guava Cache
- 主要參數
- Caffeine
- Spring注解緩存
- 分布式存儲
- Database
- AUTOCOMMIT
- 臟讀&幻讀&不可重復讀
- 子查詢
- 連接
- 內連接
- 自連接
- 自然連接
- 外連接
- 組合查詢
- 隔離級別
- 數據庫范式
- 索引實現機制
- 數據庫拆分
- 表分區
- 分庫
- 分表
- MySQL
- MySQL基礎架構
- 鎖分類
- 排它鎖&獨占鎖
- 共享鎖
- 間隙鎖
- 表級鎖
- 存儲引擎
- 磁盤IO
- 磁盤結構圖
- 磁盤數據讀寫原理
- MySQL索引原理
- B+樹索引
- 局部性原理
- 索引數據結構
- 聯合索引
- 最左前綴匹配原則
- 建索引的幾大原則
- 數據文件和索引文件
- 執行計劃explain
- 常見問題
- 數據頁
- MYSQL單表存儲量計算
- 回表
- 索引覆蓋
- 索引下推
- 頁分裂和頁合并
- InnoDB
- innodb索引
- Innodb引擎的底層實現
- MyISAM
- MyISAM引擎的底層實現
- MVCC
- Next-Key Locks
- MySQL索引類型
- MYSQL復制
- 主從復制
- 讀寫分離
- MySQL Dual-Master
- 分庫分表實現方案
- MySQL事務實現原理
- MYSQL調優
- 性能優化
- HBase
- 不停機分庫分表遷移
- RDBMS&NoSQL
- 分布式事務
- 協議或事務模型
- X/Open XA協議
- 分布式事務編程接口規范JTA
- TCC模型
- 解決方案
- 兩階段提交2PC
- 三階段提交3PC
- Seata
- 分布式事務Seata產品模塊
- AT模式
- TCC模式
- Saga模式
- XA模式
- 基于消息中間件的最終一致性事務方案
- 消息隊列
- AMQP
- JMS
- ActiveMQ
- RabbitMQ
- RocketMQ
- RocketMQ基本概念
- 主要特性
- 分區順序消息
- 全局順序消息
- 消息可靠性
- 定時消息
- 消息重試
- 死信隊列
- 分布式事務消息
- RocketMQ架構
- Producer
- Consumer
- NameServer
- Broker
- RocketMQ設計
- 消息存儲
- 頁緩存與內存映射
- 消息刷盤
- 通信機制
- console控制臺
- RocketMQ部署架構
- Kafka
- Pulsar
- MQ消息重復消費與丟失
- 主流消息隊列比較
- 分布式調度系統
- 分布式搜索
- 分布式計算
- 架構案例
- 秒殺業務
- 秒殺整體架構
- 常見的監控系統
- 小米手機搶購秒殺方案
- 架構師領導藝術
- 架構師箴言
- 技術leader核心職責
- WEB服務器
- Servlet
- Servlet實現
- Servlet生命周期
- Servlet容器工作模式
- Servlet工作原理
- servlet線程安全
- CGI&FastCGI
- CGI
- FastCGI
- FastCGI與CGI特點
- CGI與Servlet比較
- HTTP Server
- Nginx
- Apache
- Nginx與Apache比較
- Application Server
- Tomcat
- Tomcat總體架構
- Connector
- 連接器核心功能
- ProtocolHandler
- EndPoint
- Processor
- Adapter
- Container
- 請求定位Servlet的過程
- Lifecycle生命周期
- Tomcat模塊設計
- Tomcat實例
- Tomcat運行原理
- spring & servlet
- Tomcat啟動流程
- Tomcat支持的I/O模型
- Tomcat應用層協議
- Tomcat類加載機制
- Tomcat類加載器
- Tomcat類加載器層次
- Apache+Tomcat
- 序列化
- XML&JSON
- JSON
- JAVA原生序列化
- hessian
- 常見中間件
- Canal
- Databus
- ELK日志套件
- 數據庫連接池
- spring狀態機
- 常見解決方案
- 二維碼掃碼登錄原理
- 前沿技術
- Saas服務
- 服務網格(Service Mesh)
- 云原生
- 常見面試問題
- Redis持久化的幾種方式
- Redis的緩存失效策略
- 附錄
- 二將軍問題
- 常見問題定位步驟
- 如何快速熟悉新系統
- 制定技術方案套路
- NUMA陷阱