TCC 是支付场景里最常见的分布式事务方案之一。它把“扣款”拆成 Try、Confirm、Cancel 三个阶段,降低锁持有时间,并保留强一致性能力。
CAP 理论
分布式系统无法同时满足:
- 一致性
- 可用性
- 分区容忍性
现实里分区容忍性几乎必选,因此在一致性与可用性之间做权衡。
2PC 简述
2PC 通过协调者控制提交与回滚,保证原子性。
优势:清晰、易实现。
缺点:同步阻塞、单点风险、故障下不一致。
TCC 适用场景
TCC 作用于服务层,不依赖底层存储或 RPC 框架。
核心价值:
- 跨服务事务一致性
- 锁时间短,吞吐更高
- 支持二阶段异步化
TCC 接口设计
三类异常
- 空回滚
- 幂等
- 悬挂(Cancel 先于 Try)
处理思路
Try:插入事务记录,确保可追踪,若已完成二阶段则拒绝。
Confirm:检查事务状态,重复提交直接返回。
Cancel:允许空回滚,但必须写入状态,阻止后续 Try。
TCC 优化
同库模式
分支事务记录落在业务库,不依赖独立 TC 库。
优点:简单、可靠。缺点:需要异步扫描未完成事务。
异步化
允许二阶段延迟执行,适合高峰期资金压力。
同库模式表设计
CREATE TABLE `transaction_tab_0000` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL,
`transaction_id` bigint(20) unsigned NOT NULL,
`transaction_type` tinyint(3) NOT NULL DEFAULT '0',
`status` tinyint(3) NOT NULL,
`amount` bigint(20) NOT NULL,
`create_time` bigint(20) NOT NULL DEFAULT '0',
`update_time` bigint(20) NOT NULL DEFAULT '0',
`ext_biz` bigint(20) unsigned NOT NULL,
`ext_order_no` varchar(256) NOT NULL,
`extra_data` JSON,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_transaction_id` (`transaction_id`),
UNIQUE KEY `uk_ext_index` (`ext_order_no`, `ext_biz`, `transaction_type`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `wallet_change_tab_0000` (
`wallet_change_id` bigint(20) unsigned NOT NULL,
`user_id` bigint(20) NOT NULL,
`transaction_id` bigint(20) unsigned NOT NULL,
`wallet_id` bigint(20) unsigned NOT NULL,
`wallet_type` int(10) unsigned NOT NULL,
`balance_old` bigint(20) NOT NULL,
`balance_new` bigint(20) NOT NULL,
`create_time` bigint(20) unsigned NOT NULL,
`extra_data` JSON,
PRIMARY KEY (`wallet_change_id`),
KEY `idx_transaction_id` (`transaction_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `wallet_tab_0000` (
`wallet_id` bigint(20) unsigned NOT NULL,
`wallet_type` tinyint(3) unsigned NOT NULL,
`user_id` bigint(20) unsigned NOT NULL,
`balance` bigint(20) NOT NULL,
`create_time` bigint(20) unsigned NOT NULL,
`update_time` bigint(20) unsigned NOT NULL,
`version` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`wallet_id`),
UNIQUE KEY `uniq_user_id_wallet_type` (`user_id`, `wallet_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
交易状态与类型
交易状态:
- tried
- confirmed
- canceled
交易类型:
- Topup
- Payment
- Transfer
- Withdrawal
- Request
资金流示例
用户资金流:
- Try:deposit → moneyout
- Confirm:moneyout → settlement
- Cancel:moneyout → deposit
中间账户资金流:
- Try:settlement → moneyin
- Confirm:moneyin → deposit
- Cancel:moneyin → settlement
TCC 示例
Try
START TRANSACTION;
SELECT wallet FOR UPDATE WHERE uid=123;
INSERT transaction -- txn_type: payment, status: tried
INSERT wallet_change;
UPDATE wallet SET deposit = deposit - 100, moneyout = moneyout + 100 WHERE uid=user_id;
COMMIT;
Confirm
START TRANSACTION;
SELECT wallet FOR UPDATE WHERE uid=123;
UPDATE transaction SET status='confirmed' WHERE ...;
INSERT wallet_change;
UPDATE wallet SET moneyout = moneyout - 100, settlement = settlement + 100 WHERE uid=user_id;
COMMIT;
Cancel
START TRANSACTION;
SELECT wallet FOR UPDATE WHERE uid=123;
UPDATE transaction SET status='canceled' WHERE ...;
INSERT wallet_change;
UPDATE wallet SET moneyout = moneyout - 100, deposit = deposit + 100 WHERE uid=user_id;
COMMIT;
小结
TCC 是支付系统的“强一致性工具箱”。用它的关键不是接口,而是对异常场景的完整覆盖和对幂等的严格执行。