php 实现tcc

TCC模式简介
TCC(Try-Confirm-Cancel)是一种分布式事务解决方案,通过业务逻辑拆分实现最终一致性。包含三个阶段:
- Try:预留资源,完成业务检查
- Confirm:确认执行业务操作
- Cancel:取消执行,释放预留资源
PHP实现TCC核心组件
事务管理器
class TccTransactionManager {
private $transactions = [];
public function begin($transactionId) {
$this->transactions[$transactionId] = [
'status' => 'trying',
'participants' => []
];
}
public function registerParticipant($transactionId, $participant) {
$this->transactions[$transactionId]['participants'][] = $participant;
}
public function confirm($transactionId) {
foreach ($this->transactions[$transactionId]['participants'] as $p) {
$p->confirm();
}
unset($this->transactions[$transactionId]);
}
public function cancel($transactionId) {
foreach ($this->transactions[$transactionId]['participants'] as $p) {
$p->cancel();
}
unset($this->transactions[$transactionId]);
}
}
参与者接口
interface TccParticipant {
public function try();
public function confirm();
public function cancel();
}
实现示例:订单服务
Try阶段实现
class OrderService implements TccParticipant {
public function try() {
// 冻结库存/预创建订单
$order = Order::create(['status' => 'pending']);
return ['order_id' => $order->id];
}
public function confirm() {
// 确认订单
Order::where('status', 'pending')->update(['status' => 'confirmed']);
}
public function cancel() {
// 取消订单
Order::where('status', 'pending')->delete();
}
}
事务协调流程
$tm = new TccTransactionManager();
$transactionId = uniqid();
try {
$tm->begin($transactionId);
$orderService = new OrderService();
$tm->registerParticipant($transactionId, $orderService);
// 执行Try阶段
$orderService->try();
// 所有Try成功后执行Confirm
$tm->confirm($transactionId);
} catch (Exception $e) {
// 任一Try失败执行Cancel
$tm->cancel($transactionId);
}
增强实现建议
持久化存储
class DatabaseTransactionStorage {
public function save($transactionId, $data) {
DB::table('tcc_transactions')->updateOrInsert(
['transaction_id' => $transactionId],
['data' => json_encode($data)]
);
}
}
定时任务补偿
class TccCompensator {
public function handleTimeoutTransactions() {
$expired = DB::table('tcc_transactions')
->where('created_at', '<', now()->subMinutes(30))
->get();
foreach ($expired as $tx) {
$data = json_decode($tx->data, true);
if ($data['status'] === 'trying') {
(new TccTransactionManager())->cancel($tx->transaction_id);
}
}
}
}
注意事项
- 必须实现幂等性:Confirm/Cancel可能被重复调用
- 需要记录事务日志用于故障恢复
- Try阶段应设置合理的超时时间
- 建议结合消息队列实现异步Confirm/Cancel
以上实现展示了PHP中TCC模式的核心逻辑,实际应用中需根据具体业务场景调整实现细节。分布式事务表应包含事务ID、创建时间、状态等关键字段,补偿机制需要定期扫描未完成的事务进行后续处理。







