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

Laravel Eloquent updating observer中getRawOriginal返回新值及事务兼容方案问询

问题根因说明

Laravel 框架默认的updating事件确实会在SQL写入数据库前触发,你遇到的原始值获取失效、事件看似延迟触发的问题,核心原因是事件/观察者的$afterCommit配置开启:
当观察者类中声明了public $afterCommit = true,或者对应事件的监听器配置了事务后执行,事件会推迟到整个事务提交完成后再派发,此时模型的原始值已经被新值覆盖,自然无法通过getRawOriginal拿到更新前的内容。你移除事务后逻辑恢复正常,完全符合该配置的生效逻辑。

无需移除事务的解决方案

方案1:关闭对应观察者的afterCommit配置(最优解)

直接在User观察者类中关闭事务后执行的配置,强制updating事件按默认时机触发:

class UserObserver
{
    // 新增以下配置即可
    public $afterCommit = false;

    public function updating(User $user)
    {
        Log::info('Original user', ['original' => $user->getRawOriginal('status')]);
        // 原有对比逻辑直接在这里正常执行即可
    }
}

该方案改动最小,不影响事务的其他逻辑。

方案2:更新前手动保存原始值

如果因其他业务要求必须保留$afterCommit配置,可以在调用更新方法前先查询并存储需要对比的原始值:

public function update(array $user, int $userId): ?bool
{
    $userModel = User::find($userId);
    // 提前保存需要对比的字段原始值
    $originalStatus = $userModel->getRawOriginal('status');
    
    $updateResult = $userModel->update($user);
    
    // 直接在当前位置执行值对比逻辑
    Log::info('值对比结果', [
        'original_status' => $originalStatus,
        'new_status' => $user['status'] ?? $originalStatus
    ]);

    return $updateResult;
}

方案3:使用模型saving事件替代

如果观察者的updating事件被全局配置强制要求延迟执行,可以改用更早期的saving事件监听,该事件触发时机更早,不受afterCommit配置的影响,在事务场景下也能正常拿到原始值。

内容的提问来源于stack exchange,提问作者R. Vait

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 06:15:04