TCC 分布式事务解决方案与实现
创作时间:
作者:
@小白创作中心
TCC 分布式事务解决方案与实现
引用
CSDN
1.
https://blog.csdn.net/monokai/article/details/146208675
在分布式系统中,保证数据操作的一致性是一个重要的挑战。TCC(Try-Confirm-Cancel)是一种分布式事务解决方案,通过将分布式事务分解为三个阶段(尝试、确认、取消)来确保事务的一致性和可靠性。
TCC 解决方案的工作原理
- Try 阶段:
- 在 Try 阶段,业务系统尝试执行事务操作,并预留必要的资源。
- 如果所有参与者都成功执行 Try 阶段,事务进入 Confirm 阶段。如果有任何一个参与者失败,则执行 Cancel 阶段。
- Confirm 阶段:
- 在 Confirm 阶段,业务系统确认执行事务操作,并提交事务。在这个阶段,所有资源的锁都会被释放。
- 如果 Confirm 阶段中的任何一个参与者失败,系统需要执行 Cancel 阶段。
- Cancel 阶段:
- 在 Cancel 阶段,业务系统撤销事务操作,并释放之前的资源。这个阶段用于回滚之前尝试过的操作,以保证数据的一致性。
场景案例
下面我们通过创建订单减库存这样一个案例来演示下TCC的过程。
// 全局事务上下文
// 作用:记录全局事务状态,供所有参与者共享
public class TccContext {
private String xid; // 全局事务ID
private boolean committed; // 事务提交状态
public TccContext(String xid) { this.xid = xid; }
public synchronized void commit() {
this.committed = true;
}
public boolean isCommitted() {
return committed;
}
}
// TCC 参与者接口
public interface TccParticipant {
// Try阶段:资源预留(如冻结库存)
void tryExecute(TccContext context) throws Exception;
// Confirm阶段:提交资源(如扣减库存)
void confirm(TccContext context);
// Cancel阶段:回滚资源(如释放库存)
void cancel(TccContext context);
}
参与者实现示例(订单与库存服务)
设计要点:
- Try 阶段仅执行资源预留,不实际修改业务数据
- Confirm/Cancel 操作需保证幂等性(如通过事务日志去重)
// 订单服务参与者
public class OrderParticipant implements TccParticipant {
private String orderId;
public OrderParticipant(String orderId) {
this.orderId = orderId;
}
@Override
public void tryExecute(TccContext context) throws Exception {
System.out.println("订单[" + orderId + "] Try: 创建预订单");
// 实际业务:插入预订单记录(状态为"预创建")
}
@Override
public void confirm(TccContext context) {
if (context.isCommitted()) {
System.out.println("订单[" + orderId + "] Confirm: 正式提交订单");
// 实际业务:更新订单状态为"已创建"
}
}
@Override
public void cancel(TccContext context) {
System.out.println("订单[" + orderId + "] Cancel: 删除预订单");
// 实际业务:删除预订单记录
}
}
// 库存服务参与者
public class InventoryParticipant implements TccParticipant {
private String productId;
private int quantity;
public InventoryParticipant(String productId, int quantity) {
this.productId = productId;
this.quantity = quantity;
}
@Override
public void tryExecute(TccContext context) throws Exception {
System.out.println("库存[" + productId + "] Try: 冻结" + quantity + "件");
// 实际业务:冻结库存(如 update stock set frozen = frozen + ? where product_id = ?)
}
@Override
public void confirm(TccContext context) {
if (context.isCommitted()) {
System.out.println("库存[" + productId + "] Confirm: 扣减" + quantity + "件");
// 实际业务:扣减已冻结库存(update stock set total = total - ? where product_id = ?)
}
}
@Override
public void cancel(TccContext context) {
System.out.println("库存[" + productId + "] Cancel: 释放" + quantity + "件");
// 实际业务:释放冻结库存(update stock set frozen = frozen - ? where product_id = ?)
}
}
事务协调者
- 所有参与者 Try 成功后才执行 Confirm
- 任一 Try 失败立即触发 Cancel
public class TccCoordinator {
private List<TccParticipant> participants;
private TccContext context;
public TccCoordinator(List<TccParticipant> participants, String xid) {
this.participants = participants;
this.context = new TccContext(xid);
}
public void execute() {
try {
// 阶段1:Try 资源预留
for (TccParticipant p : participants) {
p.tryExecute(context);
}
// 阶段2:Confirm 提交(假设业务逻辑通过)
context.commit();
for (TccParticipant p : participants) {
p.confirm(context);
}
} catch (Exception e) {
// 阶段3:Cancel 回滚
for (TccParticipant p : participants) {
p.cancel(context);
}
throw new RuntimeException("事务回滚: " + e.getMessage());
}
}
}
场景模拟
public class TccDemo {
public static void main(String[] args) {
// 创建参与者(订单ID=O1001,商品ID=P2001,数量2件)
TccParticipant order = new OrderParticipant("O1001");
TccParticipant inventory = new InventoryParticipant("P2001", 2);
// 事务协调(全局事务ID=TX202503121621)
TccCoordinator coordinator = new TccCoordinator(
List.of(order, inventory),
"TX202503121621"
);
// 执行事务
try {
coordinator.execute();
System.out.println("事务提交成功");
} catch (Exception e) {
System.out.println("事务失败: " + e.getMessage());
}
}
}
成功场景
订单[O1001] Try: 创建预订单
库存[P2001] Try: 冻结2件
订单[O1001] Confirm: 正式提交订单
库存[P2001] Confirm: 扣减2件
事务提交成功
失败场景(假设库存不足)
订单[O1001] Try: 创建预订单
库存[P2001] Try: 冻结2件 → 抛出异常(库存不足)
订单[O1001] Cancel: 删除预订单
库存[P2001] Cancel: 释放2件
事务失败: 事务回滚: 库存不足
TCC 的优势和适用场景
- 数据一致性:TCC 可以确保分布式事务的数据一致性,即使在出现部分故障的情况下也能够正确处理事务。
- 灵活性:TCC 允许业务系统在 Confirm 和 Cancel 阶段执行自定义的逻辑,使其更加灵活适用于不同的业务场景。
- 性能:相比于传统的两阶段提交(2PC)协议,TCC 在性能上有一定的优势,尤其在高并发场景下表现更好。
解决方案
目前市面上的TCC框架众多比如下面这几种:
框架名称 | Gitbub地址 |
|---|---|
tcc-transaction | |
Hmily | |
ByteTCC | |
EasyTransaction |
总结
TCC 是一种灵活而高效的分布式事务解决方案,通过将事务分解为 Try、Confirm 和 Cancel 阶段,确保了事务的一致性和可靠性。在设计分布式系统时,考虑使用 TCC 可能是一个不错的选择,特别是在需要更高性能和更灵活的事务管理方式时。
热门推荐
高考倒计时!这些放松技巧你必须知道
多地金融监管局发布!这份最全“避坑”指南请收好
《滕王阁序》:一篇值得背诵的千古名篇
巴黎奥运会:中国女运动员的媒介形象新高度
郑钦文:社交媒体时代女性运动员的新时代典范
舌色偏红的自我调理法:中医专家详解原因与对策
脂肪肝预防指南:从饮食到生活方式的全方位建议
Excel宏复制方法详解:VBA编辑器、导入导出与代码复制
一次预测多个token,Meta新模型推理加速3倍,编程任务提高17%
冬季狂欢必备:Tomorrowland攻略大揭秘!
乡村振兴的多元化产业发展:培育乡村新业态,打造多元化发展的美丽乡村
安居区常理镇海龙联村探索“四联四强”合作联营模式
妹妹闹离婚,家人应该如何提供帮助?
离婚后悔了怎么办:心理调适与生活重建指南
M0345,出发!青岛地铁3号线永磁牵引列车载客运营
人的三重脑:本能脑、情绪脑和理智脑
司马家是怎么夺位的:一部权力斗争的史诗
大数据治理入门:数据分类与标签管理指南
购车福利持续加码 带你读懂 2024 年购车优惠政策
《爱情公寓》里的长久承诺:你信吗?
解码男性承诺恐惧:从心理到社会的多维解析
徐立因《战地枪王》佟小凤一角爆红
宗教信仰如何影响人生意义?
存在主义:重新解读人生的意义
加缪《西西弗斯神话》:探索人生意义的新视角
冬日探秘玉溪:敦煌展览+聂耳故里双重文化盛宴
中老铁路开通三周年,玉溪外贸额破160亿!
南方周末发布ESG风险预警报告:AI赋能企业精准识别90余项风险点
企业如何应对ESG舆情风险?
揭秘蟑螂的超速逃生术:感觉系统、神经系统与身体结构的完美配合