<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Oct 16, 2013 at 2:33 PM, Galder Zamarreņo <span dir="ltr"><<a href="mailto:galder@redhat.com" target="_blank">galder@redhat.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><br>
On Oct 16, 2013, at 1:21 PM, Galder Zamarreņo <<a href="mailto:galder@redhat.com">galder@redhat.com</a>> wrote:<br>
<br>
> Guys, there's some context to this topic that Sanne has left out.<br>
><br>
> 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].<br>
><br>
> 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.<br>
><br>
> 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.<br>
><br>
> 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.<br>
><br>
> 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.<br>
><br>
> But, as Scott has found out, the TCK has some particular expectations of what happens after a evictEntityRegions or evictAll call within a transaction :(<br>
><br>
> With this in mind, let me comment on the specifics below:<br>
><br>
> [1] <a href="https://github.com/scottmarlow/wildfly/blob/b61dc1dddb1f70847d1d82206a366eedf6bc80db/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/jpa/secondlevelcache/SFSB2LC.java#L82" target="_blank">https://github.com/scottmarlow/wildfly/blob/b61dc1dddb1f70847d1d82206a366eedf6bc80db/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/jpa/secondlevelcache/SFSB2LC.java#L82</a><br>
><br>
> On Oct 2, 2013, at 1:03 AM, Sanne Grinovero <<a href="mailto:sanne@infinispan.org">sanne@infinispan.org</a>> wrote:<br>
><br>
>> I'd love to brainstorm about the clear() operation and what it means<br>
>> on Infinispan.<br>
>><br>
>> I'm not sure to what extent, but it seems that clear() is designed to<br>
>> work in a TX, or even create an implicit transaction if needed, but<br>
>> I'm not understanding how that can work.<br>
>><br>
>> Obviously a clear() operation isn't listing all keys explicitly. Which<br>
>> implies that it's undefined on which keys it's going to operate when<br>
>> it's fired.. that seems like terribly wrong in a distributed key/value<br>
>> store as we can't possibly freeze the global state and somehow define<br>
>> a set of keys which are going to be affected, while an explicit<br>
>> enumeration is needed to acquire the needed locks.<br>
>><br>
>> It might give a nice safe feeling that, when invoking a clear()<br>
>> operation in a transaction, I can still abort the transaction to make<br>
>> it cancel the operation; that's the only good part I can think of: we<br>
>> can cancel it.<br>
>><br>
>> I don't think it has anything to do with consistency though? To make<br>
>> sure you're effectively involving all replicas of all entries in a<br>
>> consistent way, a lock would need to be acquired on each affected key,<br>
>> which again implies a need to enumerate all keys, including the<br>
>> unknown keys which might be hiding in a CacheStore: it's not enough to<br>
>> broadcast the clear() operation to all nodes and have them simply wipe<br>
>> their local state as that's never going to deal correctly<br>
>> (consistently) with in-flight transactions working on different nodes<br>
>> at different times (I guess enabling Total Order could help but you'd<br>
>> need to make it mandatory).<br>
>><br>
>> So let's step back a second and consider what is the use case for<br>
>> clear() ? I suspect it's primarily a method needed during testing, or<br>
>> maybe cleanup before a backup is restored (operations), maybe a<br>
>> manually activated JMX operation to clear the cache in exceptional<br>
>> cases.<br>
><br>
> ^ 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.<br>
><br>
>> I don't think there would ever be a need for a clear() operation to<br>
>> interact with other transactions, so I'd rather make it illegal to<br>
>> invoke a clear() inside a transaction,<br>
><br>
> -1, unless you have other ideas to deal with evict calls that I mentioned above that satisfy what the TCK is after.<br>
<br>
</div></div>Btw, I'm investigating other ways to solve this particular issue, maybe by tracking which transaction made the evict call in the 2LC regions, and if any get/size calls come after that, return nothing, instead of calling clear, and just leave the clear for when a brand new transaction (different to the one that called evictAll) runs.<br>
</blockquote><div><br></div><div>If I understood the requirements correctly, it might be simpler to call clear() twice: once inside the tx, and once while the tx is suspended. That way, both the running tx and the other txs see an empty cache.<br>
<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5"><br>
><br>
>> or simply ignore the<br>
>> transactional scope and have an immediate and distributed effect.<br>
><br>
> That'd be more inline with what's needed above.<br>
><br>
>> I'm likely missing something. What terrible consequences would this have?<br>
><br>
> 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.<br>
><br>
>><br>
>> Cheers,<br>
>> Sanne<br>
>> _______________________________________________<br>
>> infinispan-dev mailing list<br>
>> <a href="mailto:infinispan-dev@lists.jboss.org">infinispan-dev@lists.jboss.org</a><br>
>> <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
><br>
><br>
> --<br>
> Galder Zamarreņo<br>
> <a href="mailto:galder@redhat.com">galder@redhat.com</a><br>
> <a href="http://twitter.com/galderz" target="_blank">twitter.com/galderz</a><br>
><br>
> Project Lead, Escalante<br>
> <a href="http://escalante.io" target="_blank">http://escalante.io</a><br>
><br>
> Engineer, Infinispan<br>
> <a href="http://infinispan.org" target="_blank">http://infinispan.org</a><br>
><br>
><br>
> _______________________________________________<br>
> infinispan-dev mailing list<br>
> <a href="mailto:infinispan-dev@lists.jboss.org">infinispan-dev@lists.jboss.org</a><br>
> <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
<br>
<br>
--<br>
Galder Zamarreņo<br>
<a href="mailto:galder@redhat.com">galder@redhat.com</a><br>
<a href="http://twitter.com/galderz" target="_blank">twitter.com/galderz</a><br>
<br>
Project Lead, Escalante<br>
<a href="http://escalante.io" target="_blank">http://escalante.io</a><br>
<br>
Engineer, Infinispan<br>
<a href="http://infinispan.org" target="_blank">http://infinispan.org</a><br>
<br>
<br>
_______________________________________________<br>
infinispan-dev mailing list<br>
<a href="mailto:infinispan-dev@lists.jboss.org">infinispan-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
</div></div></blockquote></div><br></div></div>