Uploaded image for project: 'Infinispan'
  1. Infinispan
  2. ISPN-11167

Retrying transactions after WriteSkewException should be easier

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • 10.1.0.Final
    • Core, Documentation
    • None

    Description

      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:

      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)
      

      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:

      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)
      

      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.

      Attachments

        Activity

          People

            Unassigned Unassigned
            dberinde@redhat.com Dan Berindei (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: