On 15 Dec 2011, at 10:28, Galder Zamarreño wrote:
Hi,
Re:
https://issues.jboss.org/browse/ISPN-1615,
https://issues.jboss.org/browse/ISPN-1617
and
http://lists.jboss.org/pipermail/infinispan-dev/2011-November/009577.html
I think in Infinispan 5.1, the fact that caches are either transaction or not
transactional are affecting the functionality and performance of operations such as
putForExternalRead().
The point of PFER is to make data available to other nodes and transactions which has
just been read from the database, without blocking, ignoring failures…etc.
This operation makes most sense when autoCommit is false and there's an external
transaction going on, i.e. Hibernate 2LC. As shown in ISPN-1617, this does not work (Note:
currently I have 2LC set to autoCommit=true to make this work but it's not performant
as indicated by Slorg1).
So, to make this work, we can do three things:
1. As Mircea suggested, we could start a new transaction for PFER after suspending the
on-going one. Apart from this being wasteful (suspend and start a new tx) it's
pointless because pFER is FORCE_ASYNCHRONOUS operation, so we're ignoring any failures
in other nodes to apply the data.
+1
2. Another option is to avoid suspending the transaction. Ever since
https://issues.jboss.org/browse/ISPN-1556 was implemented, a failure within a transaction
when FAIL_SILENT is on won't rollback the tx. Not suspending the tx has the advantage
of not being wasteful from a tx management perspective. The problem though is that PFER
won't be applied until the external tx has been commited, so it delays this operation.
The semantics also changes in the case the tx is rolled back, as the effect of PFER
call would not be visible (now PFER does not depend on the way the transaction completes).
I don't think this is a bad thing though.
On top of this, I have the feeling that if the cache is configured
with SYNC, this PFER might be become 2PC (mircea, can you clarify?)
yes, would
result in 2pc.
3. The third and final option is to basically allow PFER to act as non-transactional even
if the cache is transactional so that the transaction can be suspended and PFER can do its
job as quick as possible (like it did in 5.0 and before). We know PFER is an special
operation with particular options, can't we make room for this non-transactional op?
This seems to me the best middle ground between a PFER that does its job and it's
performant. I've implemented this in
https://github.com/galderz/infinispan/commit/d10fee9b2800d752695059530440... and
both the newly created test and PutForExternalReadTest pass at least (the rest of
testsuite needs checking). Mircea, WDYT?
+1, this sounds the most sensible and
clean. I'll also take a look at your impl.
Thank you for looking into this,
Mircea