]
Jive JIRA Integration updated WFLY-12337:
-----------------------------------------
Forum Reference:
Wildfly Transaction REQUIRES_NEW not working
--------------------------------------------
Key: WFLY-12337
URL:
https://issues.jboss.org/browse/WFLY-12337
Project: WildFly
Issue Type: Bug
Components: JCA, Transactions
Affects Versions: 16.0.0.Final
Reporter: Hao Chen
Assignee: Thomas Jenkinson
Priority: Major
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;