TP5中Db::update仅首个事务生效,后续事务无变更问题求助
TP5事务部分操作不生效排查问题
我在使用TP5处理支付后的事务逻辑时,遇到了一个奇怪的问题:只有事务标记transection --1里的Db::update操作能正常写入数据库,transection --2到transection --5里的update和insert操作完全没有数据变更,但整个过程没有任何错误或异常抛出。怀疑是事务隔离级别或者提交/回滚逻辑有问题,麻烦帮忙排查下事务管理逻辑,看看是不是提交方式错了或者隔离级别配置有问题。
事务处理代码
$order = db('booking_recharge')-> where('order_no',$order_no) -> where('status','0') -> find(); if($order){ file_put_contents('record_order.txt',$order); Db::startTrans(); try { // transection --1 Db::name('booking_recharge') -> where('id',$order['id']) -> update(array( 'pay_price'=>$data['data']['object']['amount_total'] * 0.01, 'pay_time' => time(), 'status' => '1', 'payment_intent'=>$payment_intent )); // Db::execute("UPDATE `fa_user` SET 'surname'='will--test' WHERE `id` = 72"); $vip = db('booking_vip') ->where('id',$order['vip_id'])-> find(); $up_user['level'] = $vip['level']; $parent = db('user') -> where('id',$user['invite_id']) -> find(); if($parent){ $out_money = 0; if($vip['level'] == 4){ $config = get_addon_config('booking'); if($config['vvip_ti'] > 0){ $out_money = bcmul($vip['price'],$vip['share_money']*0.01,2); $up_inv['out_money'] = bcadd($parent['out_money'],$out_money,2); } } // ---testing update --will if($out_money > 0) { // transection --2 Db::name('user') -> where('id',$parent['id']) -> update($up_inv); // transection --3 $log2 = array( 'user_id' => $parent['id'], 'money' => $out_money, 'before' => $parent['out_money'], 'after' => $up_inv['out_money'], 'memo' => 'push', 'createtime' => time() ); Db::name('user_outmoney_log') -> insert($log2); // db('user_outmoney_log') -> insert($log2); } } //--will $giveMoney="0"; switch($vip['level']) { case 1: $giveMoney="58"; break; case 2: $giveMoney="1000"; break; case 3: $giveMoney="10000"; break; case 4: $giveMoney="29999"; break; } $up_user['money'] = bcadd($user['money'],$giveMoney,2); if($vip['level'] == 4) { // transection --4 $up_user['yue'] = bcadd($user['yue'],"2999",2); $yue_log = array( 'user_id' => $order['user_id'], 'money' => 2999, 'before' => $user['yue'], 'after' => $up_user['yue'], 'memo' => 'push', 'createtime' => time() ); Db::name('user_yue_log') -> insert($yue_log); } file_put_contents('user_id.txt',$order['user_id']); $sql=Db::name('user') -> where('id',$order['user_id']) -> fetchSql(true) -> update($up_user); file_put_contents('fetchSql.txt',$sql); // transection --5 $money_log = array( 'user_id' => $order['user_id'], 'money' => $giveMoney, 'before' => $user['money'], 'after' => $up_user['money'], 'memo' => 'gif', 'createtime' => time() ); Db::name('user_money_log') -> insert($money_log); Db::commit(); } catch (\Exception $e) { file_put_contents('vip_exception.txt',$e); Db::rollback(); } }
排查关键点
- 数据库连接一致性:确认所有
Db::name()和db()调用是否使用同一个数据库连接。TP5中如果未指定连接名,默认使用配置的主连接,但如果中途切换了连接,事务只会在初始连接生效,其他连接的操作不在事务范围内。 - 条件有效性验证:检查后续操作的where条件是否匹配到数据,比如
parent['id']是否是有效用户ID、order['user_id']是否存在对应的记录。可以通过日志输出这些ID值,或者直接执行fetchSql(true)生成的SQL语句,看是否能正常更新数据。 - 异常捕获范围:当前仅捕获
\Exception,但TP5数据库操作可能抛出\think\db\exception\DbException等特定异常,建议改为捕获\Throwable,确保所有错误(包括Error类型)都能被捕获,避免因为静默异常导致事务未提交。 - 代码分支执行验证:确认
transection --2到transection --5所在的分支是否被执行,比如if($parent)是否为true、out_money > 0是否满足、vip['level'] ==4是否成立。可以在这些分支内添加日志输出,比如file_put_contents('branch_check.txt', '执行了parent分支的update操作')。 - 事务提交时机:检查
Db::commit()是否在所有操作完成后执行,当前代码中commit()在try块最后,逻辑上没问题,但要确保没有提前退出try块的情况。
内容的提问来源于stack exchange,提问作者Will Will
相关产品推荐
相关产品推荐

