php 实现tcc
TCC 模式简介
TCC(Try-Confirm-Cancel)是一种分布式事务解决方案,通过业务逻辑拆分实现最终一致性。核心分为三个阶段:

- Try:预留资源,完成业务检查(如冻结账户余额)。
- Confirm:确认执行,提交实际业务(如扣减余额)。
- Cancel:取消操作,释放预留资源(如解冻余额)。
PHP 实现 TCC 的关键步骤
数据库设计
创建事务记录表,存储事务状态和操作日志:
CREATE TABLE tcc_transaction (
id VARCHAR(36) PRIMARY KEY,
status ENUM('trying', 'confirmed', 'cancelled') NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
Try 阶段实现
- 生成全局事务ID(如UUID)。
- 在本地事务中插入状态为
trying的记录。 - 执行预留资源操作(如冻结余额):
// 示例代码片段 $transactionId = uniqid(); $pdo->beginTransaction(); try { $pdo->exec("INSERT INTO tcc_transaction (id, status) VALUES ('$transactionId', 'trying')"); $pdo->exec("UPDATE account SET frozen_balance = frozen_balance + 100 WHERE user_id = 1"); $pdo->commit(); } catch (Exception $e) { $pdo->rollBack(); throw $e; }
Confirm/Cancel 阶段实现
通过定时任务或消息队列触发后续操作:
// Confirm 示例
$pdo->beginTransaction();
try {
$pdo->exec("UPDATE tcc_transaction SET status = 'confirmed' WHERE id = '$transactionId'");
$pdo->exec("UPDATE account SET balance = balance - 100, frozen_balance = frozen_balance - 100 WHERE user_id = 1");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
}
// Cancel 示例
$pdo->beginTransaction();
try {
$pdo->exec("UPDATE tcc_transaction SET status = 'cancelled' WHERE id = '$transactionId'");
$pdo->exec("UPDATE account SET frozen_balance = frozen_balance - 100 WHERE user_id = 1");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
}
异常处理与重试机制
- 幂等性设计:Confirm/Cancel 操作需支持重复执行。
- 状态检查:通过定时任务扫描长时间处于
trying状态的事务,触发补偿。 - 日志记录:记录操作日志以便人工干预。
扩展建议
- 集成消息队列:使用 RabbitMQ 或 Kafka 异步触发 Confirm/Cancel。
- 使用框架:结合 Laravel 的队列系统或 Swoole 实现高性能调度。
- 分布式锁:防止并发操作导致资源冲突。
通过以上步骤,PHP 可实现基本的 TCC 模式,适用于电商、金融等需要最终一致性的场景。







