Laravel监听器执行数据库保存无报错但失败的问题排查
问题分析与解决方案
核心原因:事务上下文冲突
你在命令里做文件导入时,大概率用了数据库事务包裹整个导入流程(比如DB::transaction()),而Laravel的同步事件会继承当前的事务上下文。监听器里执行Settlement::create时,操作会被包含在主事务中——如果主事务还没提交,数据库里看不到新增数据;要是主事务后续回滚,监听器的写入也会跟着被撤销。但直接在控制台执行Settlement::create是独立事务,执行完就提交,所以能正常写入。
解决办法
1. 让监听器在事务提交后执行
在EventServiceProvider里给对应监听器加上after_commit属性,确保监听器等主事务提交后再运行:
protected $listen = [ ImportCompleted::class => [ CreateSettlementListener::class => ['after_commit' => true], ], ];
2. 手动开启独立事务
在监听器的handle方法里,用独立事务包裹写入逻辑,脱离主事务的影响:
public function handle(ImportCompleted $event) { DB::transaction(function () use ($event) { Settlement::create([ // 填入你的字段数据 ]); }); }
3. 检查模型批量赋值规则
确认Settlement模型的$fillable数组包含所有要写入的字段,或者设置$guarded = []允许全字段赋值。如果批量赋值被限制,create方法会静默失败(无报错但不写入)。
4. 查看Laravel日志
如果以上方法都无效,去storage/logs/laravel.log里排查日志,可能存在隐性报错(比如字段验证不通过、数据库权限问题),只是控制台没输出。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

