[id='invalidation-caches_{context}']
= Invalidation caches

You can use {brandname} in invalidation mode to optimize systems that perform high volumes of read operations.
A good example is to use invalidation to prevent lots of database writes when state changes occur.

This cache mode only makes sense if you have another, permanent store for your data such as a database and are only using {brandname} as an optimization in a read-heavy system, to prevent hitting the database for every read.
If a cache is configured for invalidation, every time data is changed in a cache, other caches in the cluster receive a message informing them that their data is now stale and should be removed from memory and from any local store.

ifdef::community[]
image::invalidation_cache_ispn.png[align="center", title="Invalidation cache"]
endif::community[]
ifdef::downstream[]
image::invalidation_cache_rhdg.png[align="center", title="Invalidation cache"]
endif::downstream[]

Sometimes the application reads a value from the external store and wants to write it to the local cache, without removing it from the other nodes.
To do this, it must call `Cache.putForExternalRead(key, value)` instead of `Cache.put(key, value)`.

Invalidation mode can be used with a shared cache store.
A write operation will both update the shared store, and it would remove the stale values from the other nodes' memory.
The benefit of this is twofold: network traffic is minimized as invalidation messages are very small compared to replicating the entire value, and also other caches in the cluster look up modified data in a lazy manner, only when needed.

[IMPORTANT]
====
Never use invalidation mode with a local, non-shared, cache store.
The invalidation message will not remove entries in the local store, and some nodes will keep seeing the stale value.
====

An invalidation cache can also be configured with a special cache loader, `ClusterLoader`.
When `ClusterLoader` is enabled, read operations that do not find the key on the local node will request it from all the other nodes first, and store it in memory locally.
In certain situation it will store stale values, so only use it if you have a high tolerance for stale values.

.Synchronous or asynchronous replication

When synchronous, a write blocks until all nodes in the cluster have evicted the stale value.
When asynchronous, the originator broadcasts invalidation messages but does not wait for responses.
That means other nodes still see the stale value for a while after the write completed on the originator.

.Transactions

Transactions can be used to batch the invalidation messages.
Transactions acquire the key lock on the primary owner.

With pessimistic locking, each write triggers a lock message, which is
broadcast to all the nodes.
During transaction commit, the originator broadcasts a one-phase prepare message (optionally fire-and-forget) which invalidates all affected keys and releases the locks.

With optimistic locking, the originator broadcasts a prepare message, a commit message, and an unlock message (optional).
Either the one-phase prepare or the unlock message is fire-and-forget, and the last message always releases the locks.
