GERONIMO-4576 track and show the first exception from synchronizations
git-svn-id: https://svn.apache.org/repos/asf/geronimo/components/txmanager/trunk@1076767 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java b/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
index 3a0445b..0058007 100644
--- a/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
+++ b/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
@@ -57,6 +57,7 @@
private final IdentityHashMap<XAResource, TransactionBranch> activeXaResources = new IdentityHashMap<XAResource, TransactionBranch>(3);
private final IdentityHashMap<XAResource, TransactionBranch> suspendedXaResources = new IdentityHashMap<XAResource, TransactionBranch>(3);
private int status = Status.STATUS_NO_TRANSACTION;
+ private Exception markRollbackCause;
private Object logMark;
private final Map<Object, Object> resources = new HashMap<Object, Object>();
@@ -72,6 +73,7 @@
try {
txManager.getTransactionLog().begin(xid);
} catch (LogException e) {
+ markRollbackCause(e);
status = Status.STATUS_MARKED_ROLLBACK;
SystemException ex = new SystemException("Error logging begin; transaction marked for roll back)");
ex.initCause(e);
@@ -255,19 +257,18 @@
beforePrepare();
try {
- boolean timedout = false;
if (TransactionTimer.getCurrentTime() > timeout) {
+ markRollbackCause(new Exception("Transaction has timed out"));
status = Status.STATUS_MARKED_ROLLBACK;
- timedout = true;
}
if (status == Status.STATUS_MARKED_ROLLBACK) {
rollbackResources(resourceManagers, false);
- if (timedout) {
- throw new RollbackException("Unable to commit: Transaction timeout");
- } else {
- throw new RollbackException("Unable to commit: transaction marked for rollback");
+ RollbackException rollbackException = new RollbackException("Unable to commit: transaction marked for rollback");
+ if (markRollbackCause != null) {
+ rollbackException.initCause(markRollbackCause);
}
+ throw rollbackException;
}
synchronized (this) {
if (status == Status.STATUS_ACTIVE) {
@@ -432,6 +433,7 @@
throw (SystemException) new SystemException("Error during prepare; transaction was rolled back").initCause(e);
}
synchronized (this) {
+ markRollbackCause(e);
status = Status.STATUS_MARKED_ROLLBACK;
/* Per JTA spec, If the resource manager wants to roll back the transaction,
it should do so by throwing an appropriate XAException in the prepare method.
@@ -521,12 +523,19 @@
} catch (Exception e) {
log.warn("Unexpected exception from beforeCompletion; transaction will roll back", e);
synchronized (this) {
+ markRollbackCause(e);
status = Status.STATUS_MARKED_ROLLBACK;
}
}
}
}
+ private void markRollbackCause(Exception e) {
+ if (markRollbackCause == null) {
+ markRollbackCause = e;
+ }
+ }
+
private void afterCompletion() {
// this does not synchronize because nothing can modify our state at this time
afterCompletion(interposedSyncList);
@@ -570,6 +579,7 @@
} catch (XAException e) {
log.warn("Error ending association for XAResource " + xaRes + "; transaction will roll back. XA error code: " + e.errorCode, e);
synchronized (this) {
+ markRollbackCause(e);
status = Status.STATUS_MARKED_ROLLBACK;
}
}