Why Delayed Double Delete Fails to Ensure Cache Consistency Under High Concurrency
The article dissects the delayed double‑delete pattern for Redis‑MySQL consistency, exposing its hidden pitfalls—unreliable delay timing, thread‑blocking sleeps, fragile second‑delete retries, and concurrent‑write anomalies—then recommends cache‑aside and stronger alternatives for production systems.
Many developers use the textbook recipe for Redis‑MySQL consistency: delete the cache, update the database, then wait a short period before deleting the cache again. Although the steps look simple, the article shows that in a high‑concurrency production environment this pattern becomes a serious trap.
Delay time is hard to set
The sleep interval N milliseconds must be long enough for a read request that fetched the stale value to write it back, yet short enough to avoid serving stale data to all reads. If N is too short, the second delete runs before the stale write occurs, doing nothing; if N is too long, every read sees dirty cache for the whole sleep period. Practitioners often set N to "read latency + a few hundred ms", but read latency can swing from 50 ms in normal load to 500 ms at peak, making a fixed N either wasteful or insufficient. Moreover, the delay is hard‑coded, so any change in database latency, network jitter, or scaling requires re‑evaluation.
Thread sleep blocks business threads
The naïve implementation calls Thread.sleep(500) inside the request‑handling thread. In high‑throughput scenarios each write thread blocks for the sleep duration, quickly exhausting the thread pool (e.g., 1 000 writes per second → 1 000 sleeping threads), causing queuing and time‑outs.
Moving the delay to an asynchronous mechanism such as a delayed MQ message avoids blocking, but introduces the operational cost of a message broker and new failure modes (consumer crashes, delayed consumption).
Second delete may fail
Network glitches, temporary Redis unavailability, or time‑outs can cause the second delete to fail. Handling the failure requires retries, back‑off strategies, and additional compensation logic, further increasing system complexity.
Concurrent‑write pitfalls
The double‑delete assumes a single writer and a single reader. When two writes A and B arrive concurrently, the order of cache deletion and DB update can leave the database with value Y while the cache still holds X, violating consistency. This is not a cache‑consistency issue but a fundamental concurrent‑write ordering problem that delayed double delete cannot solve.
Recommended approach
The article advocates the cache‑aside (read‑through/write‑through) strategy: always read the cache first, fall back to the database on a miss, write the result back to the cache, and on updates first modify the database then delete the cache. This eliminates the timing window because the window between DB update and cache delete is only a few microseconds.
For stronger guarantees, the author lists alternatives:
Cache Aside (update DB then delete cache) – suitable for most scenarios.
Cache Aside + TTL fallback – tolerates brief inconsistency.
Canal binlog listener + MQ async update – for high‑consistency requirements.
Distributed lock to serialize write requests – for severe write‑conflict workloads.
In summary, delayed double delete may work in low‑traffic, low‑consistency‑requirement cases, but once concurrency rises each of its assumptions breaks. Switching to cache‑aside or one of the stronger patterns yields more reliable consistency without the hidden costs.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer XiaoFu
xiaofucode.com – a programmer learning guide driven by the pursuit of profit
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
