Laravel 8.x队列Job类handle方法中数据库查询不生效如何解决
问题解决步骤
1. 修复异常类导入错误
你当前引入的是PHPUnit测试专用的异常类PHPUnit\Exception,无法捕获数据库操作抛出的常规运行异常,程序出错时不会进入catch分支输出报错,首先修改导入语句:
把use PHPUnit\Exception;替换为use Exception;
2. 重启队列加载最新代码
Laravel的queue:work命令启动后会常驻内存,修改Job代码后必须重启队列才能生效,执行以下命令重启:php artisan queue:restart
3. 增加参数合法性校验
直接多层级取payload数组的键值,只要某一层键不存在就会抛出数组不存在的错误,导致任务直接中断,建议用Laravel内置的data_get辅助函数安全取值,同时增加非空判断:
$ref = data_get($charge, 'event.data.metadata.ref'); if (empty($ref)) { info('Webhook payload未携带有效ref参数', $charge); return; }
4. 增加调试信息定位问题
在代码中增加日志输出,确认拿到的ref值和预期一致,同时打印update操作的返回值,判断是执行失败还是没有匹配到记录:
info('待更新的ref值', ['ref' => $ref]); // update返回值为匹配到的行数,返回0属于正常情况,代表没有对应ref的记录需要更新 $updateCount = DB::table('cointrades')->where('ref', $ref)->update(['status'=>'waiting']); info('更新行数', ['count' => $updateCount]);
日志会写入storage/logs/laravel.log文件,可查看对应日志确认执行情况。
修正后完整代码
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\DB; use Exception; use Shakurov\Coinbase\Models\CoinbaseWebhookCall; class HandleCreatedCharge implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** @var \Shakurov\Coinbase\Models\CoinbaseWebhookCall */ public $webhookCall; public function __construct(CoinbaseWebhookCall $webhookCall) { $this->webhookCall = $webhookCall; } public function handle() { $charge = $this->webhookCall->payload; // 安全取值 $ref = data_get($charge, 'event.data.metadata.ref'); if (empty($ref)) { info('无效的webhook请求:缺少ref参数', $charge); return; } try { $updateCount = DB::table('cointrades')->where('ref', $ref)->update(['status'=>'waiting']); info('cointrades表更新完成', ['ref' => $ref, '更新行数' => $updateCount]); } catch (Exception $exception){ info('更新数据库失败', ['错误信息' => $exception->getMessage(), 'trace' => $exception->getTraceAsString()]); // 如需队列重试可放开下方注释 // throw $exception; } } }
如果以上操作后还是执行异常,可进一步确认:cointrades表的status字段是否允许设置为waiting字符串值,ref字段的类型是否和你拿到的$ref类型一致。
内容的提问来源于stack exchange,提问作者LSIMMON
相关产品推荐
相关产品推荐

