Why hibernate-jcache is not enough (for Infinispan)
by Radim Vansa
Hi Steve,
on HipChat you've asked why hibernate-jcache + Infinispan's
implementation of JCache is not enough. It ultimately boils down to
1. performance
2. correctness
where (2) can be fine with some providers but then (1) suffers.
Infinispan offers transactional mode, but it's not serializable (gosh,
sometimes it's even read_uncommitted) and has its quirks. The
performance can't be as good as with non-tx mode, too. That's why the
native transactional caches support will be dropped in 5.3 and we'll
just emit a warning to update their configuration (and continue with
non-tx config).
As a demonstration of this we can use the putFromLoad. If you implement
this as a (ideal serializable) transactional cache putIfAbsent, the
provider must either
a) lock the key (pessimistic approach) - but we don't want to block
other nodes removing data from the cache (on write) or putFromLoading
(on read!)
b) resolve conflicts when the transaction is committing: you figure out
that there are two concurrent updates and rollback one of the
transactions - that's not acceptable to us either, as any failure in
cache should not affect DB transaction. And there's a risk of blocking
between the 2 phases of commit, too.
Theoretically you could just wipe any modified data on conflict - I
don't know if anyone does that, 'drop everything and proceed with
commit' is not something I'd expect from a general-purpose (NoSQL) DB. I
recall Alex's JCache implementation (for 5.2) storing some 'lock'
objects in the cache, and you probably don't want to wipe those.
Interaction with evictAll/removeAll could be also problematic: not sure
about the other providers but Infinispan's clear() operation is
non-transactional even on tx cache (since Infinispan 7 or so) because
it's impractical to resolve all conflicts. I don't know details how
others provide that operation but there may be a hidden problem.
Last but not least, you assume that the provider is transactional and it
provides JCache interface. JCache does not define interaction with JTA,
because it was hard to get agreement on non-tx behaviour (why did it
take 13 years to complete the JSR?) and it would be even harder for JTA.
So what you expect is just your extrapolation or wishful thinking, and
it's up to integrators to verify that the unwritten contract is
fulfilled within the scope of hibernate-jcache module use. Not that SPI
implementors would be in a better position, but at least we are aware
that (for us) it's not enough to implement those 3 classes and job's done.
Of course the correctness aspect may be ignored with 'it's just a cache'
implying 'users expect stale/uncommitted data' as Sanne (who is much
closer to the customers than me) keeps repeating. However this is not
what 2LC promises as I understand it: the same results as DB would do.
I am really grateful that in 5.3 you've provided the
CacheTransactionSynchronization that will help us boost (1) even further
by allowing us to execute all operations in parallel. And it's good that
you've made the SPI more expressive with the intent; there'll be a bunch
of TODOs in the 5.3 implementation to cover use cases that were not
handled in previous versions but now are obvious.
Cheers
Radim
--
Radim Vansa <rvansa(a)redhat.com>
JBoss Performance Team
6 years, 8 months