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

Laravel主数据变更时如何更新永久缓存数据?

解决Laravel永久缓存(Cache::rememberForever)的数据更新问题

当你用Cache::rememberForever实现永久缓存时,核心思路是在主数据发生变更时,主动清除对应缓存键——因为永久缓存不会自动过期,只有删除后,下次请求才会重新执行闭包生成新的缓存数据。下面是几个生产环境常用的最优方案:

方案1:数据变更时手动删除缓存键

这是最直接、易维护的方案,适合业务逻辑简单的场景。在处理数据更新/删除的方法中,完成数据库操作后,直接调用Cache::forget()清除对应缓存。

示例代码:

缓存读取(控制器index/show方法)

public function show(User $user)
{
    // 用用户ID作为缓存键的一部分,保证唯一性
    $userData = Cache::rememberForever("user_detail_{$user->id}", function () use ($user) {
        // 这里返回需要缓存的最终数据,比如关联了头像、角色的用户信息
        return $user->load(['avatar', 'roles']);
    });

    return view('users.show', compact('userData'));
}

数据更新时清除缓存(控制器update方法)

public function update(Request $request, User $user)
{
    // 验证并更新数据库数据
    $user->fill($request->validated())->save();

    // 清除对应永久缓存
    Cache::forget("user_detail_{$user->id}");

    return redirect()->route('users.show', $user);
}

方案2:利用模型事件自动处理缓存

如果多个地方都可能修改用户数据(比如后台、API、队列任务),手动删缓存容易遗漏。这时可以用Laravel模型事件,在数据变更时自动触发缓存清除逻辑,实现全局统一处理。

示例代码(User模型):

class User extends Model
{
    protected static function booted()
    {
        // 当用户数据被创建、更新时触发saved事件
        static::saved(function (User $user) {
            Cache::forget("user_detail_{$user->id}");
            // 如果有其他关联缓存(比如用户帖子列表),也一起删除
            Cache::forget("user_posts_{$user->id}");
        });

        // 用户被删除时触发deleted事件
        static::deleted(function (User $user) {
            Cache::forget("user_detail_{$user->id}");
        });
    }
}

这样不管通过什么方式修改用户数据,只要模型触发saved/deleted事件,缓存就会自动清除,无需在每个业务方法中重复写清除逻辑。

方案3:缓存标签批量管理(多缓存键场景)

如果一个用户对应多个缓存键(比如个人信息、帖子列表、收藏列表),一个个删除太繁琐,可以用Redis支持的缓存标签,给同一用户的所有缓存打上标签,数据变更时直接清空整个标签下的缓存。

示例代码:

带标签的缓存读取

// 用户详情缓存
$userData = Cache::tags(["user_{$user->id}"])->rememberForever('user_detail', function () use ($user) {
    return $user->load(['avatar', 'roles']);
});

// 用户帖子列表缓存
$userPosts = Cache::tags(["user_{$user->id}"])->rememberForever('user_posts', function () use ($user) {
    return $user->posts()->latest()->take(10)->get();
});

数据变更时清空标签下所有缓存

public function update(Request $request, User $user)
{
    $user->fill($request->validated())->save();

    // 清空该用户标签下的所有缓存
    Cache::tags(["user_{$user->id}"])->flush();

    return redirect()->route('users.show', $user);
}

注意事项

  • 缓存键命名要唯一:建议带上模型ID、业务标识(如user_detail_123),避免不同缓存之间冲突。
  • 缓存轻量化:尽量缓存处理后的最终数据,不要缓存整个模型实例,减少Redis内存占用。
  • 复杂列表缓存:如果是用户列表(index方法)的永久缓存,缓存键要考虑筛选条件(如user_list_active、user_list_admin),更新时要对应清除所有相关的列表缓存键。

内容的提问来源于stack exchange,提问作者Rasoul Karimi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:25:32