You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 09:35:55