How to Ensure Data Consistency Between Cache and Database: Strategies and Trade‑offs
This article examines the challenges of keeping cache and database data synchronized, categorizes data by real‑time requirements, and evaluates four cache‑write strategies—updating the database first, deleting cache first, and their variations—highlighting their advantages, pitfalls, and practical solutions such as delayed double deletion, forced master reads, and binlog‑driven cache updates.
How to Ensure Data Consistency Between Cache and Database?
When optimizing a system, data can be tiered based on real‑time requirements: some configuration data changes rarely, while order and transaction data require high immediacy.
Level 1: Order and payment transaction data – high real‑time and precision requirements, accessed directly from the database without any cache.
Level 2: User‑related data – read‑heavy, write‑light, cached in Redis.
Level 3: Payment configuration data – small volume, frequent reads, almost never modified, cached in local memory.
Using any cache (local memory or Redis) introduces data synchronization issues because the cache cannot automatically detect changes made directly to the database, leading to inconsistencies.
Solutions
We list several strategies and discuss their pros and cons.
Update the database first, then update the cache.
Update the database first, then delete the cache.
Update the cache first, then update the database.
Delete the cache first, then update the database.
Update the database first, then update the cache
This approach is rarely used because updating the cache can be costly when the cached value requires complex calculations. If many write requests occur with few reads, updating the cache on every write incurs heavy performance overhead.
For example, if a database value is 1 and ten requests increment it, updating the cache each time creates a lot of stale data. Deleting the cache instead allows a single cache refresh when a read occurs.
Update the cache first, then update the database
This scenario is essentially the same as the first and is generally not considered.
Delete the cache first, then update the database
This can cause inconsistency. Consider two requests: A (update) and B (read). Request A deletes the Redis entry and updates the database, while request B sees an empty cache, reads from the database, and repopulates the cache before A’s transaction commits, leading to stale data.
The simplest remedy is the delayed double‑delete strategy.
However, even after the transaction commits, read‑write splitting in MySQL can cause a lag between master and replica, leading to stale reads.
When request A deletes Redis and updates the master, a subsequent read (request B) may hit the replica before replication finishes, retrieving outdated data. The fix is to force cache‑populating queries to read from the master.
Update the database first, then delete the cache
If the cache deletion fails after a successful database update, subsequent reads will return stale data.
A common solution is to use a message queue for compensating deletions: after a failed cache delete, the key is sent to a queue, and a consumer retries the deletion.
Request A updates the database.
Cache deletion fails and the key is sent to a message queue.
The consumer receives the message and attempts the Redis deletion again.
While effective, this tightly couples business code with infrastructure. An alternative is to subscribe to MySQL binlog events and update the cache based on those logs, decoupling the systems.
Conclusion
Each strategy has trade‑offs. Deleting the cache before updating the database can be solved by forcing reads to the master, which adds code intrusion but no extra services. Using binlog subscription isolates the cache layer but increases system complexity. The optimal choice depends on specific business requirements; there is no one‑size‑fits‑all solution.
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.
Java High-Performance Architecture
Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.
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.
