Guys, there's some context to this topic that Sanne has left out.

This discussion origins comes from Scott Marlow who's found a bug in a 
Hibernate 2LC test. The test itself can be found in [1].

Basically, the test loads a couple of entities into the 2LC, and then calls 
evictAll in the cache that evicts all entities from the 2LC. Then, it expects 
the size of the cache to be 0 and entities to be gone from the 2LC.

The 2LC has a peculiar way to deal with evictEntityRegions or evictAll, it 
doesn't just call clear() and hope for the best. Instead, it marks the cache as 
invalid, and next time someone queries the cache, it clears it in a separate 
transaction. This is done cluster wide too by sending messages to other node 
that the cache region is invalid.

The problem here is that because it's done in a separate transaction, it 
doesn't have an impact on the on going transaction, so the assertions after 
evict fail. IOW, we implemented evict as a "eventually clear", where eventually 
all transactions will stop using the cached data, but any current transactions 
will still see data. We did this for performance reasons and to avoids the 
issues Sanne mentiones below.

The problem is that we didn't envision this evict method to be used in such 
way. I always assumed this would be run outside of a transaction. IOW, you'd 
use this when you've updated the database separately (i.e. script, PL/SQL) and 
you want to clear the 2LC. I always thought that'd be something run via JMX or 
separate from another transaction. 

But, as Scott has found out, the TCK has some particular expectations of what 
happens after a evictEntityRegions or evictAll call within a transaction :(

With this in mind, let me comment on the specifics below:

[1] 
https://github.com/scottmarlow/wildfly/blob/b61dc1dddb1f70847d1d82206a366eedf6bc80db/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/jpa/secondlevelcache/SFSB2LC.java#L82

On Oct 2, 2013, at 1:03 AM, Sanne Grinovero <[email protected]> wrote:

> I'd love to brainstorm about the clear() operation and what it means
> on Infinispan.
> 
> I'm not sure to what extent, but it seems that clear() is designed to
> work in a TX, or even create an implicit transaction if needed, but
> I'm not understanding how that can work.
> 
> Obviously a clear() operation isn't listing all keys explicitly. Which
> implies that it's undefined on which keys it's going to operate when
> it's fired.. that seems like terribly wrong in a distributed key/value
> store as we can't possibly freeze the global state and somehow define
> a set of keys which are going to be affected, while an explicit
> enumeration is needed to acquire the needed locks.
> 
> It might give a nice safe feeling that, when invoking a clear()
> operation in a transaction, I can still abort the transaction to make
> it cancel the operation; that's the only good part I can think of: we
> can cancel it.
> 
> I don't think it has anything to do with consistency though? To make
> sure you're effectively involving all replicas of all entries in a
> consistent way, a lock would need to be acquired on each affected key,
> which again implies a need to enumerate all keys, including the
> unknown keys which might be hiding in a CacheStore: it's not enough to
> broadcast the clear() operation to all nodes and have them simply wipe
> their local state as that's never going to deal correctly
> (consistently) with in-flight transactions working on different nodes
> at different times (I guess enabling Total Order could help but you'd
> need to make it mandatory).
> 
> So let's step back a second and consider what is the use case for
> clear() ? I suspect it's primarily a method needed during testing, or
> maybe cleanup before a backup is restored (operations), maybe a
> manually activated JMX operation to clear the cache in exceptional
> cases.

^ Well, that's precisely the problem of second level cache evictEntityRegions 
or evictAll. In some scenarios, the clear is expected to affect the ongoing 
transaction too, see above use case from the TCK.

> I don't think there would ever be a need for a clear() operation to
> interact with other transactions, so I'd rather make it illegal to
> invoke a clear() inside a transaction,

-1, unless you have other ideas to deal with evict calls that I mentioned above 
that satisfy what the TCK is after.

> or simply ignore the
> transactional scope and have an immediate and distributed effect.

That'd be more inline with what's needed above.

> I'm likely missing something. What terrible consequences would this have?

p.s. For the 2LC use case, I'm trying to see if the clear() could be done in 
the same transaction and see if that helps, but no luck yet as that causes 
other failures.

> 
> Cheers,
> Sanne
> _______________________________________________
> infinispan-dev mailing list
> [email protected]
> https://lists.jboss.org/mailman/listinfo/infinispan-dev


--
Galder Zamarreño
[email protected]
twitter.com/galderz

Project Lead, Escalante
http://escalante.io

Engineer, Infinispan
http://infinispan.org


_______________________________________________
infinispan-dev mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/infinispan-dev

Reply via email to