Uploaded image for project: 'WildFly'
  1. WildFly
  2. WFLY-12337

Wildfly Transaction REQUIRES_NEW not working

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • 16.0.0.Final
    • JCA, Transactions
    • None
    • Hide

      If I removed the <cached-connection-manager/> in standalone.xml, then REQUIRES_NEW transaction is working as expected.

      Show
      If I removed the <cached-connection-manager/> in standalone.xml, then REQUIRES_NEW transaction is working as expected.

    Description

      We recently upgraded from jboss-eap-6.4 to Wildfly 16. Most things worked fine until we find one issue in the case that a method that is called using TransactionTemplate with TransactionDefinition.PROPAGATION_REQUIRES_NEW is not working...

      The case is that: we use this PROPAGATION_REQUIRES_NEW transaction to commit a log of login failure, while the main transaction is rolled back due login exception.

      This used to work without problem in jboss-eap-6.4 though we were seeing warnings like:

      Trying to change transaction TransactionImple < ac, BasicAction: 0:ffff0a004b01:513406f2:5d37ce0b:2a0 status: ActionStatus.RUNNING > in enlist!

      But in Wildfly 16 PROPAGATION_REQUIRES_NEW doesn't work any more – the new transaction seems to rolled back together with the main transaction. After spending quite some time debugging into the Wildfly/Jboss code, I found that in org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist method, there is a new line:

      if (isEnlisted() || getState().equals(ConnectionState.DESTROY) || getState().equals(ConnectionState.DESTROYED))
      return;

      And in our case, the TxConnectionListener object is the same in the new transaction as in the old transaction, so it's already marked as "enlisted". And therefore the rest of enlist is never executed for the new transaction, so Wildfly never issued a "XA Start" command for the new transaction.

      So the question is: is the added isEnlisted() check a bug introduced or there is something wrong we did to configure Wildfly and/or Spring? How should the REUIRES_NEW case work?

      Here is a trace except I captured:

      TransactionTemplate.execute(TransactionCallback<T>) line: 130 JtaTransactionManager(AbstractPlatformTransactionManager).getTransaction(TransactionDefinition) line: 353 JtaTransactionManager(AbstractPlatformTransactionManager).handleExistingTransaction(TransactionDefinition, Object, boolean) line: 433
      JtaTransactionManager.doBegin(Object, TransactionDefinition) line: 831
      JtaTransactionManager.doJtaBegin(JtaTransactionObject, TransactionDefinition) line: 872
      LocalUserTransaction.begin() line: 48
      ContextTransactionManager.begin(CreationListener$CreatedBy) line: 62
      LocalTransactionContext.beginTransaction(int, boolean, CreationListener$CreatedBy) line: 188 JBossJTALocalTransactionProvider(JBossLocalTransactionProvider).createNewTransaction(int)
      ...
      ContextTransactionManager.resume(AbstractTransaction) line: 158
      LocalTransaction.resume() line: 248
      TransactionManagerDelegate(BaseTransactionManagerDelegate).resume(Transaction) line: 122
      TransactionManagerImple.resume(Transaction) line: 111
      AtomicAction.resume(AtomicAction) line: 361
      LocalTransaction(AbstractTransaction).notifyAssociationListeners(boolean) line: 115
      TransactionManagerService$2.associationChanged(AbstractTransaction, boolean) line: 97
      UserTransactionRegistry.userTransactionStarted() line: 119
      UserTransactionListenerImpl.userTransactionStarted() line: 52
      CachedConnectionManagerImpl.userTransactionStarted() line: 249
      TxConnectionManagerImpl.transactionStarted(Collection<ConnectionRecord>) line: 460
      TxConnectionListener.enlist() line: 264
      !-- changed in ironjacamar-core-impl-1.2
      // If we are already enlisted there is no reason to check again, as this method
      // could be called multiple times during a transaction lifecycle.
      // We know that we can only be inside this method if we are allowed to
      if (isEnlisted() || getState().equals(ConnectionState.DESTROY) || getState().equals(ConnectionState.DESTROYED))
      return;

      Attachments

        Activity

          People

            smaestri@redhat.com Stefano Maestri
            hchen00@gmail.com Hao Chen (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: