Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

Vlad Mihalcea

HOME BLOG STORE TRAINING CONSULTING TUTORIALS VIDEOS TALKS

How does Let’s


connect

Hibernate
NONSTRICT_RE
AD_WRITE
CacheConcurrenc
yStrategy work Find
Article

Last modified: Jan 22, 2019


Search …Go
Follow @vlad_mihalcea

Imagine having a tool that can automatically detect if


you are using JPA and Hibernate properly. Book

Hypersistence Optimizer is that tool!

Introduction
In my previous post, I introduced the READ_ONLY
CacheConcurrencyStrategy, which is the obvious choice
Video
for immutable entity graphs. When cached data is Course

changeable,
Privacy wesite
& Cookies: This need
usesto use aByread-write
cookies. continuing tocaching strategy
use this website, you agree to their use.
To find out more, including how to control cookies, see here: Our Cookie Policy Close and accept
and this post will describe how
NONSTRICT_READ_WRITE second-level cache works.

https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 1/9
11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

Inner workings
Vlad Mihalcea

When BLOG
HOME the Hibernate transaction
STORE is committed,
TRAINING the
CONSULTING TUTORIALS VIDEOS TALKS

following sequence of operations is executed:

Hypersistence
Optimizer

ERP
Contact

Online
Workshop

First, the cache is invalidated before the database


transaction gets committed, during flush time:

1. The current Hibernate Transaction (e.g.


JdbcTransaction, JtaTransaction) is flushed Consulting

2. The DefaultFlushEventListener executes the current


ActionQueue

3. The EntityUpdateAction calls the update method of


Privacy the EntityRegionAccessStrategy
& Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Our Cookie Policy Close and accept
4. The
NonStrictReadWriteEhcacheCollectionRegionAccessStrategy

https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 2/9
11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

removes the cache entry from the underlying


Vlad EhcacheEntityRegion
Mihalcea

HOME BLOG STORE TRAINING CONSULTING TUTORIALS VIDEOS TALKS


After the database transaction is committed, the cache
entry is removed once more:

Adobe
Creative
1. The current Hibernate Transaction after completion
Cloud for
callback is called Teams
starting at
2. The current Session propagates this event to its $33.99 per
internal ActionQueue month.

3. The EntityUpdateAction calls the afterUpdate ADS VIA CARBO

method on the EntityRegionAccessStrategy

4. The
NonStrictReadWriteEhcacheCollectionRegionAccessStrategy
calls the remove method on the underlying
EhcacheEntityRegion
Em
Inconsistency warning Get
it
The NONSTRICT_READ_WRITE mode is not a write-
through caching strategy but a read-through cache
Now
concurrency mode because cache entries are invalidated,
instead of being updated. The cache invalidation is not
synchronized with the current database transaction. Even
if the associated Cache region entry gets invalidated twice
(before and after transaction completion), there’s still a tiny
time window when the cache and the database might drift
apart.

The following test will demonstrate this issue. First, we are


going
Privacy to define
& Cookies: This Alice transaction
site uses logic: to use this website, you agree to their use.
cookies. By continuing
To find out more, including how to control cookies, see here: Our Cookie Policy Close and accept

1 doInTransaction(session -> {
2 LOGGER.info("Load and modify Reposito
3 Repository repository = (Repository)
https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 3/9
11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

4 session.get(Repository.class, 1L)
5
Vlad MihalceaassertTrue(getSessionFactory().getCac
6 .containsEntity(Repository.class,
7 repository.setName("High-Performance
8 applyInterceptor.set(true);
HOME 9 BLOG
}); STORE TRAINING CONSULTING TUTORIALS VIDEOS TALKS
10
11 endLatch.await();
12
13 assertFalse(getSessionFactory().getCache(
14 .containsEntity(Repository.class, 1L)
15
16 doInTransaction(session -> {
17 applyInterceptor.set(false);
18 Repository repository = (Repository)
19 session.get(Repository.class, 1L)
20 LOGGER.info("Cached Repository {}", r
21 });

Alice loads a Repository entity and modifies it in her first


database transaction.
To spawn another concurrent transaction right when Alice
prepares to commit, we are going to use the following
Hibernate Interceptor:

1 private AtomicBoolean applyInterceptor =


2 new AtomicBoolean();
3
4 private final CountDownLatch endLatch =
5 new CountDownLatch(1);
6
7 private class BobTransaction extends Empt
8 @Override
9 public void beforeTransactionCompleti
10 if(applyInterceptor.get()) {
11 LOGGER.info("Fetch Repository
12
13 assertFalse(getSessionFactory
14 .containsEntity(Repositor
15
16 executeSync(() -> {
17 Session _session = getSes
18 .openSession();
19 Repository repository = (
20 _session.get(Reposito
21 LOGGER.info("Cached Repos
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
22 repository);
To find out more, including how to control cookies, see here: Our Cookie Policy Close and accept
23 _session.close();
24 endLatch.countDown();
25 });
26

https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 4/9
11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

27 assertTrue(getSessionFactory(
Vlad28
Mihalcea }
29
.containsEntity(Repositor

30 }
31 }
HOME BLOG STORE TRAINING CONSULTING TUTORIALS VIDEOS TALKS

Running this code generates the following output:

1 [Alice]: Load and modify Repository


2 [Alice]: select nonstrictr0_.id as id1_0_
3 [Alice]: update repository set name='High
4
5 [Alice]: Fetch Repository from another tr
6 [Bob]: select nonstrictr0_.id as id1_0_0_
7 [Bob]: Cached Repository from Bob's trans
8
9 [Alice]: committed JDBC Connection
10
11 [Alice]: select nonstrictr0_.id as id1_0_
12 [Alice]: Cached Repository Repository{id=

1. Alice fetches a Repository and updates its name

2. The custom Hibernate Interceptor is invoked and


Bob’s transaction is started

3. Because the Repository was evicted from the


Cache, Bob will load the 2nd level cache with the
current database snapshot

4. Alice transaction commits, but now the Cache


contains the previous database snapshot that Bob’s
just loaded

5. If a third user will now fetch the Repository entity, he


will also see a stale entity version which is different
from the current database snapshot

6. After Alice transaction is committed, the Cache entry


is evicted again and any subsequent entity load
request will populate the Cache with the current
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
database
To find out snapshot
more, including how to control cookies, see here: Our Cookie Policy Close and accept

https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 5/9
11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

Stale data vs lost


Vlad Mihalcea

HOME
updatesBLOG STORE TRAINING CONSULTING TUTORIALS VIDEOS TALKS

The NONSTRICT_READ_WRITE concurrency strategy


introduces a tiny window of inconsistency when the
database and the second-level cache can go out of sync.
While this might sound terrible, in reality, we should always
design our applications to cope with these situations even
if we don’t use a second-level cache. Hibernate offers
application-level repeatable reads through its transactional
write-behind first-level cache and all managed entities are
subject to becoming stale. Right after an entity is loaded
into the current Persistence Context, another concurrent
transaction might update it and so, we need to prevent
stale data from escalating to losing updates.

Optimistic concurrency control is an effective way of


dealing with lost updates in long conversations and this
technique can mitigate the NONSTRICT_READ_WRITE
inconsistency issue as well.

If you enjoyed this article, I bet you are going to love


my Book and Video Courses as well.

Conclusion
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
The NONSTRICT_READ_WRITE concurrency strategy is Close and accept
To find out more, including how to control cookies, see here: Our Cookie Policy
a good choice for read-mostly applications (if backed-up
by the optimistic locking mechanism). For write-intensive

https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 6/9
11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

scenarios, the cache invalidation mechanism would


Vlad Mihalcea
increase the cache miss rate, therefore rendering this
technique inefficient.
HOME BLOG STORE TRAINING CONSULTING TUTORIALS VIDEOS TALKS

Code available on GitHub.

Follow @vlad_mihalcea

Enter your email address

DOWNLOAD NOW

Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Our Cookie Policy Close and accept

Related
https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 7/9
11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

Vlad
HowMihalcea
does How does High-Performance
Hibernate Hibernate Java Persistence -
READ_WRITE TRANSACTIONAL Part Two
HOME BLOG STORE TRAINING
CacheConcurren… CacheConcurren… CONSULTING
In "Hibernate" TUTORIALS VIDEOS TALKS
work work
In "Hibernate" In "Hibernate"

Category: Hibernate  Tags: caching, concurrency


control, hibernate, nonstrict, read-write, Training, Tutorial

← How does Hibernate Collection Cache work


How does Hibernate READ_WRITE CacheConcurrencyStrategy
work →

Leave a Reply
Your email address will not be published. Required
fields are marked *

Comment

Before posting the comment, please take the


time to read the FAQ page

Name *

Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
Email
To find out more,*including how to control cookies, see here: Our Cookie Policy Close and accept

Website
https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 8/9
11/6/2020 How does Hibernate NONSTRICT_READ_WRITE CacheConcurrencyStrategy work - Vlad Mihalcea

Vlad Mihalcea
Notify me of follow-up comments by email.

HOME BLOG STORE TRAINING CONSULTING TUTORIALS VIDEOS TALKS


Post Comment

This site uses Akismet to reduce spam. Learn how


your comment data is processed.

Tu t o r i a l s Social About Meta


Media

Hibernate About Log in


Twitter
SQL FAQ Entries feed
Facebook
Comments feed
Spring Archive
YouTube
WordPress.org
Git Privacy Policy
GitHub
FlexyPool Terms of Service
LinkedIn

Vlad Mihalcea
Powered by WordPress.com.      

Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Our Cookie Policy Close and accept

https://vladmihalcea.com/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work/ 9/9

You might also like