From tadamski at redhat.com Tue Aug 16 13:04:46 2016 From: tadamski at redhat.com (Tomasz Adamski) Date: Tue, 16 Aug 2016 13:04:46 -0400 (EDT) Subject: [jbossts-dev] Why does com.arjuna.ats.internal.jts.orbspecific.coordinator.ArjunaTransactionImple throw INVALID or Inactive when we know the status is ABORTED? In-Reply-To: <1447116704.1914091.1471366987306.JavaMail.zimbra@redhat.com> Message-ID: <1723738386.1914204.1471367086618.JavaMail.zimbra@redhat.com> I have hit a race condition where the EJB interceptors and the reaper are both aborting a transaction simultaneously. If the reaper doesn't finish rollback before ejb thread enters it then the ejb thread gets INVALID_TRANSACTION (via ArjunaTransactionImple) (even though the transaction is still on the thread). ArjunaTransactionImple knows that the status is ActionStatus.ABORTED but elects to throw INVALID_TRANSACTION. By changing the code to throw TRANSACTION_ROLLEDBACK instead the EJB interceptor thread can correctly reason about the aborted transaction. More specifically, here are the two possible outcomes depending on the order in which both threads execute com.arjuna.ats.internal.jts.ControlWrapper code: Scenario 1: * reaper executes ControlWrapper#rollback method first * server executes ControlWrapper#rollback; line _controlImpl.getImplHandle().rollback() throws an NullPointerException as ArjunaTransactionImple has been already detached exception is caught and TransactionRolledbackException is thrown Scenario 2: * both threads enter ControlWrapper#rollback at the same time * server thread obtains ArjunaTransactionImple; transaction is in ABORTED state so InvalidTransaction exception is thrown Attempt to synchronize the code: synchronized (_controlImpl) { _controlImpl.getImplHandle().rollback(); } on _controlImpl object doesn't work as it introduces possible deadlock to the code. Another possibility would be to check transaction status inside ArjunaTransactionImple#rollback method and throw TransactionRolledbackException when transaction is already aborted. I have tested such fix in my branch and it fixes the initial error - TransactionRolledbackException is thrown consistently. Is such fix possible to introduce? Are there some problems that it may introduce? -- Tomasz Adamski Software Engineer JBoss by Red Hat From tom.jenkinson at redhat.com Wed Aug 17 06:11:15 2016 From: tom.jenkinson at redhat.com (Tom Jenkinson) Date: Wed, 17 Aug 2016 11:11:15 +0100 Subject: [jbossts-dev] Why does com.arjuna.ats.internal.jts.orbspecific.coordinator.ArjunaTransactionImple throw INVALID or Inactive when we know the status is ABORTED? In-Reply-To: <1723738386.1914204.1471367086618.JavaMail.zimbra@redhat.com> References: <1447116704.1914091.1471366987306.JavaMail.zimbra@redhat.com> <1723738386.1914204.1471367086618.JavaMail.zimbra@redhat.com> Message-ID: Hi Tomasz, Seems like a bug to me, there is already a question mark around it: https://github.com/jbosstm/narayana/blob/master/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java#L443 I think you should raise a Jira and a PR would of course be appreciated. However, I think you probably just want the CW:rollbacl() it to drop into https://github.com/jbosstm/narayana/blob/master/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java#L526 Thanks, Tom PS: this list is kind of almost zero traffic, most people discuss development questions on the Developer sub-space over here: https://developer.jboss.org/en/jbosstm/dev/content?filterID=contentstatus%5bpublished%5d~objecttype~objecttype%5bthread%5d - thanks! On 16 August 2016 at 18:04, Tomasz Adamski wrote: > I have hit a race condition where the EJB interceptors and the reaper are > both aborting a transaction simultaneously. If the reaper doesn't finish > rollback before ejb thread enters it then the ejb thread gets > INVALID_TRANSACTION (via ArjunaTransactionImple) (even though the > transaction is still on the thread). ArjunaTransactionImple knows that the > status is ActionStatus.ABORTED but elects to throw INVALID_TRANSACTION. By > changing the code to throw TRANSACTION_ROLLEDBACK instead the EJB > interceptor thread can correctly reason about the aborted transaction. > > More specifically, here are the two possible outcomes depending on the > order in which both threads execute com.arjuna.ats.internal.jts.ControlWrapper > code: > > Scenario 1: > * reaper executes ControlWrapper#rollback method first > * server executes ControlWrapper#rollback; line > _controlImpl.getImplHandle().rollback() throws an NullPointerException as > ArjunaTransactionImple has been already detached exception is caught and > TransactionRolledbackException is thrown > Scenario 2: > * both threads enter ControlWrapper#rollback at the same time > * server thread obtains ArjunaTransactionImple; transaction is in ABORTED > state so InvalidTransaction exception is thrown > > Attempt to synchronize the code: > > synchronized (_controlImpl) { > _controlImpl.getImplHandle().rollback(); > } > > on _controlImpl object doesn't work as it introduces possible deadlock to > the code. Another possibility would be to check transaction status inside > ArjunaTransactionImple#rollback method and throw > TransactionRolledbackException when transaction is already aborted. I have > tested such fix in my branch and it fixes the initial error - > TransactionRolledbackException is thrown consistently. > > Is such fix possible to introduce? Are there some problems that it may > introduce? > > > -- > Tomasz Adamski > Software Engineer > JBoss by Red Hat > > _______________________________________________ > jbossts-dev mailing list > jbossts-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/jbossts-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/jbossts-dev/attachments/20160817/b076d2e5/attachment.html