High-Performance Java Persistence – Chapter 16 – Caching
Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Wouldn’t that be just awesome?
Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, or Play Framework.
So, enjoy spending your time on the things you love rather than fixing performance issues in your production system on a Saturday night!
Part 2, Chapter 16
Every new chapter of my book is released right after it’s being completed, so the reader doesn’t have to wait for the whole part to be finished to get access to new material.
Table of content
This chapter explains how enterprise caching works, from database internal buffers, to application-level caching, and the second-level cache offered by Hibernate.
16. Caching 16.1 Caching flavors 16.2 Cache synchronization strategies 16.2.1 Cache-aside 16.2.2 Read-through 16.2.3 Write-invalidate 16.2.4 Write-through 16.2.5 Write-behind 16.3 Database caching 16.4 Application-level caching 16.4.1 Entity aggregates 16.4.2 Distributed key/value stores 16.4.3 Cache synchronization patterns 16.4.4 Synchronous updates 16.4.5 Asynchronous updates 16.4.5.1 Change data capture 16.5 Second-level caching 16.5.1 Enabling the second-level cache 16.5.2 Entity cache loading flow 16.5.3 Entity cache entry 16.5.3.1 Entity reference cache store 16.5.4 Collection cache entry 16.5.5 Query cache entry 16.5.6 Cache concurrency strategies 16.5.6.1 READ_ONLY 16.5.6.1.1 Inserting READ_ONLY cache entries 16.5.6.1.2 Updating READ_ONLY cache entries 16.5.6.1.3 Deleting READ_ONLY cache entries 16.5.6.2 NONSTRICT_READ_WRITE 16.5.6.2.1 Inserting NONSTRICT_READ_WRITE cache entries 16.5.6.2.2 Updating NONSTRICT_READ_WRITE cache entries 16.5.6.2.3 Risk of inconsistencies 16.5.6.2.4 Deleting NONSTRICT_READ_WRITE cache entries 16.5.6.3 READ_WRITE 16.5.6.3.1 Inserting READ_WRITE cache entries 16.5.6.3.2 Updating READ_WRITE cache entries 16.5.6.3.3 Deleting READ_WRITE cache entries 16.5.6.3.4 Soft locking concurrency control 16.5.6.4 TRANSACTIONAL 16.5.6.4.1 XA_Strict mode 16.5.6.4.2 XA mode 16.5.6.4.3 Inserting TRANSACTIONAL cache entries 16.5.6.4.4 Updating TRANSACTIONAL cache entries 16.5.6.4.5 Deleting TRANSACTIONAL cache entries 16.5.7 Query cache strategy 16.5.7.1 Table space query invalidation 16.5.7.2 Native SQL statement query invalidation
Chapter summary
Caching is everywhere, and enterprise systems are no different. Before jumping to an application-level cache, it’s important to know that most database systems are designed to make use of caching, as mush as possible. Some database systems come with their own shared buffers, whereas others rely on the underlying operating system for caching disk pages in memory.
Even after tuning the database, to overcome the networking overhead, and to level-up traffic spikes, it’s common to use an application-level cache, like Redis or Memcached.
These key-value stores can be distributed on several nodes, therefore providing increased availability and data sharding capabilities. One major advantage of storing entity aggregates in a key-value database is that the application can work in a read-only mode even when the entire database cluster is down, for maintenance.
The only downside for using an application-level cache is to ensure that the two separate sources of data do not drift apart. For this reason, there are several cache concurrency strategies: cache-aside, read-through, write-through.
Being tightly coupled with Hibernate, thee second-level cache can speed up reads, without compromising data consistency. However, choosing the right cache concurrency strategy (READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTION) requires understanding the inner-workings of the cache update policy. The entity query cache has its own rules, and because it employs an aggresive cache invalidation policy, it only applies to a certain data access pattern criteria.
With almost 60 pages, the Caching chapter is one of the largest chapters of this book, so enjoy reading High-Performance Java Persistence!
