On 01/22/2016 05:26 PM, Steve Ebersole wrote:
On Fri, Jan 22, 2016 at 9:30 AM Radim Vansa <rvansa(a)redhat.com
<mailto:rvansa@redhat.com>> wrote:
On 01/22/2016 03:11 PM, Steve Ebersole wrote:
> On Fri, Jan 22, 2016 at 7:21 AM Radim Vansa <rvansa(a)redhat.com
<mailto:rvansa@redhat.com>
> <mailto:rvansa@redhat.com <mailto:rvansa@redhat.com>>> wrote:
>
> Why should the strategy 'never be used if serializable
transaction
> isolation level is required'? What guarantees it gives, and what
> in ORM
> core depends on this? When I've asked the last time, Steve said
> that all modes but the
>
> nonstrict one require that the 2LC is absolutely transparent
> (consistency-wise), so you always get the same answer as if
you were
> directly talking to DB.
>
>
> I would guess this is talking about "serializable isolation" at the
> application layer. Yes extended across both the application and
> database. In our original implementations we had no L2 cache
> providers that would support serializable isolation. Does
> hibernate-infinispan? If we ask for a certain entry from the
cache in
> T1, T2 adds that entry and commits, and then we ask for it again
in T1
> do we still see it as "not existing"? I'd highly doubt it, but
if it
> does then lets make note of that.
No, without a transactional cache, it does not. Thanks for the
example.
But will the request get to 2LC, or will it be served already from
Session cache?
It won't work even with a transactional cache I believe. It won't work
with Infinispan e.g. I do not think. Hibernate does not keep reference
to "non-existing" entities. That's the only way the Session could
"serve" the fact that the first T1 lookup found nothing. Again, this
gets right back to that idea of consistency. Without L2 caching, in
this scenario with serializable isolation the database would return me
"no row" in both T1 SELECTs.
Infinispan keeps 'transactional context' for the current transaction and
stores all reads there, even if this is a null read. However, as I've
checked the distribution code, it still does the remote lookup (which
escapes the transaction) and the value could get there even with
so-called repeatable reads. I'll check infinispan-dev why.
> Does the ' you should ensure that the transaction is completed when
> `Session.close()` or `Session.disconnect()` is called' still
hold, or
> does the transactional rework in 5.0 somehow obsolete this info?
>
>
> I cannot say why this is discussed in a chapter on caching.
> Session#disconnect is largely deprecated (its main use case is
handled
> much more transparently now). IMO it's always a good idea to make
> sure a transaction against a resource is completed prior to closing
> that transaction. That's no different for a Hibernate Session
then it
> is for a JDBC Connection, etc.
Did you meant 'commit the transaction before closing the session'? If
the Session.close() is called with tx open, will the transaction be
committed? But any way, this should be really the same as without 2LC.
I meant to say " make sure a transaction against a resource is
completed prior to closing that resource". Saying "complete the
transaction" != "commit the transaction". Completion might be either
commit or rollback. But the idea is that it is in a definitive state.
Historically what a stranded transaction at the time of Session#close
meant depended on the JDBC driver. Most drivers rollback back on a
stranded transaction; Oracle has always been the notable exception as
they would commit a stranded transaction. But regardless in terms of
Session locks etc in the cache that would strand the locks as well iirc.
In developing 5.0 and the new transaction handling I know we talked
about making this more deterministic, specifically always handling
this as if a rollback had been called. But to be honest, that's not
what I am seeing in the code. Andrea, do you remember? If not, we
should definitely add some tests for this to see what happens atm and
make sure its really what we want to have happen moving forward.
> Basically this passage is a poorly worded hint. What it is
trying to
> convey is that for "asynchronous" cache access what drives the
> interactions with the Cache is the Hibernate transaction, and in
these
> case the user should take extra care to make sure that the
transaction
> is handled properly. That still holds true.
>
> As a refresher, the idea of "synchronous" versus
"asynchronous" is
> simply cache access that is driven by JTA ("synchronous") versus
those
> that are driven by local transactions ("asynchronous").
Eh, I probably don't get the exact meaning of 'driving the access' :-/
And I can't find any reference to 'async' in user guide.
I keep pointing y'all to
org.hibernate.cache.spi.access.EntityRegionAccessStrategy,
org.hibernate.cache.spi.access.CollectionRegionAccessStrategy, etc as
the best source for this information. I spent a lot of time
documenting (javadoc) these contracts as I developed them.
sync/async is discussed there. No need for it to be discussed in the
user guide IMO, its a concept for developers of cache implementations
to understand not users.
Okay, this sync/async. Sure, then it makes sense that it's not in user
guide. But pardon my confusion, that class documents which methods are
used by sync/async strategies, and what's the order of method
invocation, but I never got what is the idea behind the sync/async
strategy differentiation. As I've started messing with ORM only after
the 5.0 tx rework, I always considered the difference between JTA and
local transactions just an implementation detail orthogonal to 2LC.
Radim
--
Radim Vansa <rvansa(a)redhat.com>
JBoss Performance Team