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

Rails应用缓存问题:数据库数据已删除但Redis缓存仍存在

Fixing Redis Cache Inconsistency After Deleting Snippets

Hey there! The issue you're running into makes total sense—let's break it down and fix it quickly.

What's Going Wrong

Your current after_save :clear_cache callback only triggers when a Snippet is created or updated. When you run @snippet.destroy, Rails doesn't fire the after_save hook—so your Redis cache key "snippets" never gets deleted, leaving stale data behind.

The Fix: Cover Delete Operations in Your Callbacks

You have two solid options to make sure the cache gets cleared after deletions:

Option 1: Use after_commit (Recommended)

after_commit triggers after a database transaction is successfully committed, which covers create, update, AND destroy operations. This is more reliable than separate hooks because it avoids edge cases where a transaction might roll back but you've already cleared the cache.

Update your Snippet model like this:

class Snippet < ApplicationRecord
  # Trigger clear_cache after create, update, or destroy commits
  after_commit :clear_cache, on: [:create, :update, :destroy]

  def clear_cache
    $redis.del("snippets")
  end
end

Option 2: Add an after_destroy Hook

If you prefer to keep separate hooks, explicitly add after_destroy :clear_cache to cover deletion events:

class Snippet < ApplicationRecord
  after_save :clear_cache
  after_destroy :clear_cache

  def clear_cache
    $redis.del("snippets")
  end
end

Why This Works

Now when you delete a Snippet, the clear_cache method will run, deleting the "snippets" key from Redis. The next time someone hits the index action, your fetch_snippets helper will detect the missing cache key, pull the latest data from the database, and repopulate the cache with the updated list.

Just a quick check: make sure your fetch_snippets helper logic correctly re-populates the cache when it's missing. It should look something like this (adjust if your implementation differs):

# In SnippetsHelper
def fetch_snippets
  cached_snippets = $redis.get("snippets")
  if cached_snippets
    JSON.parse(cached_snippets)
  else
    snippets = Snippet.all.to_a
    $redis.set("snippets", snippets.to_json)
    snippets
  end
end

That should resolve the inconsistency—your cache will now stay in sync with the database after deletes!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:04:20