Hi,
The concurrency TCK currently has test code for this in the
"DeploymentDescriptorTests" (simplified):
@Resource
UserTransaction tx;
ContextService contextSvc =
InitialContext.doLookup("java:global/concurrent/ContextD");
tx.begin();
try {
checkContextAndGetTransactionStatus =
contextSvc.contextualCallable(() -> {
return tx.getStatus(); // unchanged
});
int status =
checkContextAndGetTransactionStatus.call();
assertEquals(status, Status.STATUS_ACTIVE);
} finally {
tx.rollback();
}
In GlassFish, this fails as the TX is committed after the
call to the ContextService.
What happens is that after the callable is invoked, there
is a reset; contextSetupProvider.reset(contextHandleForReset);
Which eventually does this:
if (transactionManager != null) {
// clean up after user if a transaction is still
active
// This is not required by the Concurrency spec
Transaction transaction =
transactionManager.getCurrentTransaction();
if (transaction != null) {
try {
int status = transaction.getStatus();
if (status == Status.STATUS_ACTIVE) {
transactionManager.commit();
} else if (status ==
Status.STATUS_MARKED_ROLLBACK) {
transactionManager.rollback();
}
} catch (Exception ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
ex.toString());
}
}
transactionManager.clearThreadTx();
}
As the comment already says, it's not required to commit /
cleanup, so to pass this test which assumes the TX stays open,
I could simply remove the cleanup, or maybe not call reset in
the first place, or perhaps add a new alternative reset
method.
Do any of the GlassFish or Concurrency RI committers have
any thoughts on this? The behaviour could be changed at both
places, and may have some consequences elsewhere.
Kind regards,
Arjan Tijms