Laravel如何在保存模型前获取ID,仅支付成功时保存记录?
解决方案
要实现「仅支付成功时才保存交易到数据库」的需求,有两种可靠的实现方式:
方法一:预生成交易ID(推荐)
先获取数据库中transactions表的下一个自增ID,用它生成支付网关需要的交易标识,待支付成功后再创建交易记录,从根源避免无效数据入库。
代码示例:
public function makeDeposit($amount, Pool $pool, $payment_method_id, $payment_number, $user_id) { if ($payment_method_id === 1) { // 获取transactions表的下一个自增ID $nextId = DB::select("SHOW TABLE STATUS LIKE 'transactions'")[0]->Auto_increment; $transactionRef = "XMZDEP" . $nextId; // 调用自定义支付网关 $result = $this->depositWithCustomGateway($transactionRef, $payment_number, $amount, $transactionRef); if ($result->status == 200 || $result->status == 201) { // 支付成功,正式创建交易记录 $deposit = Transaction::create([ 'pool_id' => $pool->id, 'user_id' => $user_id, 'amount' => $amount, 'payment_method_id' => $payment_method_id, 'transaction_type' => 'deposit', 'reference' => $transactionRef // 可选:存储网关交易标识 ]); return $deposit; } else { throw new TransactionException($result->response->output_ResponseCode . " - " . $result->response->output_ResponseDesc, $result->status); } } }
方法二:利用数据库事务回滚
先创建交易记录,通过数据库事务包裹操作,支付失败时触发回滚,删除已创建的无效交易。
代码示例:
public function makeDeposit($amount, Pool $pool, $payment_method_id, $payment_number, $user_id) { if ($payment_method_id === 1) { return DB::transaction(function () use ($amount, $pool, $payment_number, $user_id) { // 临时创建交易记录(事务未提交,不会持久化) $deposit = Transaction::create([ 'pool_id' => $pool->id, 'user_id' => $user_id, 'amount' => $amount, 'payment_method_id' => 1, 'transaction_type' => 'deposit', ]); $transactionRef = "XMZDEP" . $deposit->id; $result = $this->depositWithCustomGateway($transactionRef, $payment_number, $amount, $transactionRef); if ($result->status != 200 && $result->status != 201) { // 支付失败,抛出异常触发事务回滚 throw new TransactionException($result->response->output_ResponseCode . " - " . $result->response->output_ResponseDesc, $result->status); } // 支付成功,事务自动提交,交易记录持久化 return $deposit; }); } }
两种方法对比
- 预生成ID:无多余数据库写入操作,性能更优,适合高并发场景;
- 事务回滚:逻辑更直观,依赖数据库事务机制保障数据一致性,但会产生「写入-回滚」的额外开销。
内容的提问来源于stack exchange,提问作者Muhammad Puspaceno
相关产品推荐
相关产品推荐

