Dan Berindei created ISPN-11167:
-----------------------------------
Summary: Retrying transactions after WriteSkewException should be easier
Key: ISPN-11167
URL:
https://issues.redhat.com/browse/ISPN-11167
Project: Infinispan
Issue Type: Bug
Components: Core, Documentation
Affects Versions: 10.1.0.Final
Reporter: Dan Berindei
Fix For: 11.0.0.Final
I've added the documentation tag because we "know" users of optimistic
transactions
should catch {{WriteSkewException}}s and retry, but the user guide never explains how a
user should do it.
It turns out the exception tree is really complicated:
{noformat}
javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
at
com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1299) Suppressed:
javax.transaction.xa.XAException
at
org.infinispan.transaction.impl.TransactionCoordinator.prepare(TransactionCoordinator.java:143)
Caused by: org.infinispan.remoting.RemoteException: ISPN000217: Received exception
from ...
at
org.infinispan.remoting.transport.ResponseCollectors.wrapRemoteException(ResponseCollectors.java:25)
Suppressed: org.infinispan.util.logging.TraceException
at
org.infinispan.interceptors.impl.SimpleAsyncInvocationStage.get(SimpleAsyncInvocationStage.java:39)
Caused by: org.infinispan.transaction.WriteSkewException: Write skew detected on key ...
at
org.infinispan.marshall.exts.ThrowableExternalizer.readObject(ThrowableExternalizer.java:257)
{noformat}
Part of the problem is internal: we shouldn't wrap {{WriteSkewException}} in a
{{RemoteException}}.
The other part is harder to control: Narayana makes our {{XAException}} a suppressed
exception instead of a cause,
probably because in the general case multiple XA resources could fail to prepare.
Initially I thought the XAException was suppressed because Narayana committed the
transaction in one phase,
but I disabled {{CoordinatorEnvironmentBean.commitOnePhase}} and it's still
suppressed.
OTOH the exception tree could be much simpler with {{useSynchronization(true)}},
if it weren't for our own gratuitous wrapping:
{noformat}
javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
at
com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1299)
Caused by: org.infinispan.commons.CacheException: Could not prepare.
at
org.infinispan.transaction.impl.TransactionTable.beforeCompletion(TransactionTable.java:898)
Caused by: javax.transaction.xa.XAException
at
org.infinispan.transaction.impl.TransactionCoordinator.prepare(TransactionCoordinator.java:143)
Caused by: org.infinispan.remoting.RemoteException: ISPN000217: Received exception from
...
at
org.infinispan.remoting.transport.ResponseCollectors.wrapRemoteException(ResponseCollectors.java:25)
Suppressed: org.infinispan.util.logging.TraceException
at
org.infinispan.interceptors.impl.SimpleAsyncInvocationStage.get(SimpleAsyncInvocationStage.java:39)
Caused by: org.infinispan.transaction.WriteSkewException: Write skew detected on key ...
at
org.infinispan.marshall.exts.ThrowableExternalizer.readObject(ThrowableExternalizer.java:257)
{noformat}
We could remove the {{CacheException}}, the {{XAException}}, and the {{RemoteException}},
leaving just a {{RollbackException}} caused by a {{WriteSkewException}}.
For implicit transactions we add yet another wrapper:
sync operations wrap the {{RollbackException}} in a {{CacheException}},
async operations wrap it in a {{CompletionException}}.
We could instead check if the exception is caused by a {{WriteSkewException}} and unwrap
it.
We should definitely add a helper static method for the users to check if they should
retry the transaction,
something like {{CacheTransactions.isWriteSkew(RollbackException)}},
and we should change the write skew to use it.
Currently they are content to catch a {{RollbackException}} and assume it has a
{{WriteSkewException}} inside.
We should also add a {{useSynchronization}} parameter to
{{AbstractClusteredWriteSkewTest}} and all the write skew tests.
--
This message was sent by Atlassian Jira
(v7.13.8#713008)