[
http://jira.jboss.com/jira/browse/JBAS-4972?page=comments#action_12387500 ]
Adrian Brock commented on JBAS-4972:
------------------------------------
This issue is really a duplicate of JBAS-4803 which contained no useful information,
not even how to reproduce it.
Now that I can reproduce it, it is easy to see that Spring is trying to register an
transaction
synchronization after it has marked the transaction for rollback.
The relevant logging is this part.
2007-11-14 14:46:38,949 DEBUG [org.springframework.transaction.jta.JtaTransactionManager]
Setting JTA transaction rollback-only
2007-11-14 14:46:38,949 DEBUG [org.springframework.transaction.jta.JtaTransactionManager]
Registering after-completion synchronization with existing JTA transaction
org.springframework.transaction.NoTransactionException: No active JTA transaction
at
org.springframework.transaction.jta.JtaTransactionManager.registerAfterCompletionWithExistingTransaction(JtaTransactionManager.java:834)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCompletion(AbstractPlatformTransactionManager.java:871)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:774)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:722)
Looking at the source I have for Spring (version 2.0.2) this is a bug in
org.springframework.transaction.support.AbstractPlatformTransactionManager::processRollback(...)
/**
* Process an actual rollback.
* The completed flag has already been checked.
* @param status object representing the transaction
* @throws TransactionException in case of rollback failure
*/
private void processRollback(DefaultTransactionStatus status) {
try {
try {
triggerBeforeCompletion(status);
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back
transaction to savepoint");
}
status.rollbackToHeldSavepoint();
}
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction
rollback");
}
doRollback(status);
}
else if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() ||
isGlobalRollbackOnParticipationFailure()) {
if (status.isDebug()) {
logger.debug(
"Participating transaction failed - marking existing transaction as
rollback-only");
}
// ===========> HERE IT MARKS THE TRANSACTION FOR ROLLBACK
doSetRollbackOnly(status);
}
else {
if (status.isDebug()) {
logger.debug(
"Participating transaction failed - letting transaction originator decide on
rollback");
}
}
}
else {
logger.debug("Should roll back transaction
but cannot - no transaction available");
}
}
catch (RuntimeException ex) {
triggerAfterCompletion(status,
TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
catch (Error err) {
triggerAfterCompletion(status,
TransactionSynchronization.STATUS_UNKNOWN);
throw err;
}
// ================> HERE IS WHERE IT TRIES TO REGISTER THE AFTER COMPLETION
triggerAfterCompletion(status,
TransactionSynchronization.STATUS_ROLLED_BACK);
}
Probably something is wrong with this method in the same class where instead of running
the
after completion inline it is trying to register it with the now defunct transaction.
i.e. the if statement is going is taking the wrong branch
BUT THAT IS ONLY A GUESS, I DON'T KNOW THE SPRING CODEBASE
/**
* Trigger <code>afterCompletion</code> callbacks.
* @param status object representing the transaction
* @param completionStatus completion status according to
TransactionSynchronization constants
*/
private void triggerAfterCompletion(DefaultTransactionStatus status, int
completionStatus) {
if (status.isNewSynchronization()) {
List synchronizations =
TransactionSynchronizationManager.getSynchronizations();
if (!status.hasTransaction() || status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Triggering afterCompletion
synchronization");
}
// No transaction or new transaction for the current scope
->
// invoke the afterCompletion callbacks immediately
invokeAfterCompletion(synchronizations,
completionStatus);
}
else {
// Existing transaction that we participate in, controlled
outside
// of the scope of this Spring transaction manager ->
try to register
// an afterCompletion callback with the existing (JTA)
transaction.
registerAfterCompletionWithExistingTransaction(status.getTransaction(),
synchronizations);
}
}
}
jboss 4.2.1 with spring 2.0.6 causes NoTransactionException
-----------------------------------------------------------
Key: JBAS-4972
URL:
http://jira.jboss.com/jira/browse/JBAS-4972
Project: JBoss Application Server
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: Transaction Manager
Affects Versions: JBossAS-4.2.1.GA, JBossAS-4.2.2.GA
Reporter: Adrian Brock
Assigned To: Adrian Brock
Attachments: earmodule-1.0.ear, server.log.zip, springejb.zip
This issue was raised in the forums and the attachments sent to me private e-mail.
"
Hi Adrian,
In the topic
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4084161
you were asking for more information or some code that reproduces the problem.
I created a small ear that contains an EJB, a spring bean and a JSP.
The JSP calls the EJB which calls the Spring bean.
I tested the ear with both jboss 4.2.1 and 4.2.2 and got the same error.
In order to simulate the error, please do the following:
- Install jboss 4.2.1 or 4.2.2
- Copy the earmodule-1.0.ear to
<jboss_home>\server\default\deploy\
- Copy spring.jar, from <springframework 2.0.6 distribution>\dist\ to
<jboss_home>\server\default\lib\
(I could not attach the jar to this email because your email server complains that the
zip is too big)
- Additionally add to <jboss_home>\server\default\conf\jboss-log4j.xml the
following in order to see how spring is using the transaction started by EJB
to enlist the spring bean (UserBo):
<category name="org.springframework.transaction">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<priority value="DEBUG"/>
</category>
and if you want to see more details at console about spring transaction manager,
change the Threshold of CONSOLE appender to DEBUG.
- Start jboss
- To trigger the error, open in a browser the URL:
http://localhost:8080/test/
I attached the source and the ear to this email + the server log from jboss 4.2.2.
Like I said in the topic, this was not happening on jboss 4.0.4.
Could you please take a look and do a debug perhaps.
Thank you.
I look forward to hearing from you.
Best Regards,
Bucegi Omu
"
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira