Reputation: 7332
A service tier that implements its persistence based on JPA can profit hugely from the second-level cache that is managed transparently by the JPA provider (e.g. Hibernate, Toplink/Toplink Essentials etc.). When this cache is activated, it holds instances of the persistent classes as soon as they were loaded from the database for the first time. There may be vendor-specific extensions to configure the cache behaviour.
The JPA standard also supports optimistic locking by having a timestamp or version field that is used to avoid data corruption when concurrent updates occur. As this mechanism relies on the data contained in the database it can also be used when other applications or services want to update the data - just include the version field of the record in the update and you're done.
When it comes to caching, the behaviour seems to be that the JPA provider (at least Toplink Essentials) does not notice changes in the database that aren't performed using the EntityManager.
Is this really the default behaviour and the responsibility to update/invalidate the JPA provider cache is up to the application? If yes, this seems quite counter-intuitive to the fact that most databases are used by many different applications.
Upvotes: 3
Views: 1104
Reputation: 21
We've successfully used PostgreSQL LISTEN/NOTIFY to keep our second-level (client-side) caches up-to-date. Since PostgreSQL 9.0, NOTIFY also supports specifying a payload. We implemented it in C++ and using ODBC but JPA/JDBC also provide such features.
The procedure is more complex but provides better performance than flushing the full cache or not using cache at all, especially if some relations are relatively rarely updated.
The essence of the procedure is:
LISTEN
s on specific event (e.g. "MYTABLE"
)MYTABLE
record the changes (e.g. event timestamp, opcode and primary key) into a table MYTABLE_NY
and send a notification: NOTIFY MYTABLE
EVENT_TIMESTAMP > last_cache_refresh
) in MYTABLE_NY
.session.evict()
or cache.evictEntity()
The result is a cache implementation that contains up-to-date data within one second of any transaction closed on the database server. We used it primarily for AutoComplete with no problem, i.e. it is even feasible for highly interactive usage of cached data.
I can provide some code samples if interested.
Upvotes: 1
Reputation: 26796
This behavior is also true for Hibernate (19.2. The Second Level Cache):
Be aware that caches are not aware of changes made to the persistent store by another application. They can, however, be configured to regularly expire cached data.
This sounds reasonable. How should your cache know about any changes done by another application if this one doesn't use the cache? The only possibility left for the cache/JPA provider would be to monitor the database (all tables, all data) for changes and update accordingly. This isn't really feasible.
I've also read that it's strongly discouraged to use the second-level cache when multiple applications change the same data in the database, for the above mentioned reasons.
Upvotes: 3