[Mulgara-svn] r1482 - trunk/src/jar/resolver/java/org/mulgara/resolver
ronald at mulgara.org
ronald at mulgara.org
Thu Feb 12 17:59:57 UTC 2009
Author: ronald
Date: 2009-02-12 09:59:56 -0800 (Thu, 12 Feb 2009)
New Revision: 1482
Modified:
trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransaction.java
trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
Log:
Attempting to improve reporting of heuristic rollbacks to application by keeping
track of the cause for the last error and including that in the exceptions.
Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java 2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java 2009-02-12 17:59:56 UTC (rev 1482)
@@ -147,7 +147,7 @@
return new MulgaraTransactionException(errorMessage, cause);
} finally {
completed = true;
- factory.transactionComplete(this);
+ factory.transactionComplete(this, rollbackCause);
}
} finally {
releaseMutex();
@@ -469,6 +469,10 @@
return heurCode;
}
+ String getRollbackCause() {
+ return rollbackCause;
+ }
+
boolean isRollbacked() {
return rollback;
}
@@ -604,7 +608,7 @@
private void cleanupTransaction() throws XAException {
report("cleanupTransaction");
try {
- factory.transactionComplete(this);
+ factory.transactionComplete(this, rollbackCause);
} catch (MulgaraTransactionException em) {
try {
logger.error("Failed to cleanup transaction", em);
Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java 2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java 2009-02-12 17:59:56 UTC (rev 1482)
@@ -48,11 +48,13 @@
private final MulgaraXAResourceContext xaResource;
private MulgaraExternalTransaction associatedTransaction;
+ private String lastRollbackCause;
public MulgaraExternalTransactionFactory(DatabaseSession session, MulgaraTransactionManager manager) {
super(session, manager);
this.associatedTransaction = null;
+ this.lastRollbackCause = null;
this.transactions = new HashSet<MulgaraExternalTransaction>();
this.xaResource = new MulgaraXAResourceContext(this, session);
}
@@ -61,7 +63,10 @@
acquireMutex(0, MulgaraTransactionException.class);
try {
if (associatedTransaction == null) {
- throw new MulgaraTransactionException("No externally mediated transaction associated with session");
+ throw new MulgaraTransactionException(
+ "No externally mediated transaction associated with session" +
+ (lastRollbackCause != null ? " - last transaction was rolled back with error: " +
+ lastRollbackCause : ""));
} else if (write && associatedTransaction != writeTransaction) {
throw new MulgaraTransactionException("RO-transaction associated with session when requesting write operation");
}
@@ -91,6 +96,7 @@
xa = new MulgaraExternalTransaction(this, xid, session.newOperationContext(true));
writeTransaction = xa;
associatedTransaction = xa;
+ lastRollbackCause = null;
transactions.add(xa);
transactionCreated(xa);
@@ -98,13 +104,14 @@
} catch (Throwable th) {
manager.releaseWriteLock(session);
if (xa != null)
- transactionComplete(xa);
+ transactionComplete(xa, th.toString());
throw new MulgaraTransactionException("Error initiating write transaction", th);
}
} else {
try {
MulgaraExternalTransaction xa = new MulgaraExternalTransaction(this, xid, session.newOperationContext(false));
associatedTransaction = xa;
+ lastRollbackCause = null;
transactions.add(xa);
transactionCreated(xa);
@@ -131,7 +138,7 @@
}
}
- public void transactionComplete(MulgaraExternalTransaction xa)
+ public void transactionComplete(MulgaraExternalTransaction xa, String rollbackCause)
throws MulgaraTransactionException {
acquireMutex(0, MulgaraTransactionException.class);
try {
@@ -147,6 +154,7 @@
transactions.remove(xa);
if (associatedTransaction == xa) {
associatedTransaction = null;
+ lastRollbackCause = rollbackCause;
}
} finally {
releaseMutex();
Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransaction.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransaction.java 2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransaction.java 2009-02-12 17:59:56 UTC (rev 1482)
@@ -512,7 +512,7 @@
context.clear();
enlisted.clear();
state = State.FAILED;
- factory.transactionAborted(this);
+ factory.transactionAborted(this, rollbackCause);
return new MulgaraTransactionException("Transaction rollback triggered", cause);
case DEACTREF:
throw new IllegalStateException("Attempt to rollback deactivated transaction");
@@ -567,6 +567,8 @@
// need to rollback this transaction, but if we have reached here
// we have failed to obtain a valid transaction to rollback!
try {
+ if (rollbackCause == null) rollbackCause = cause;
+
try {
errorReport(errorMessage + " - Aborting", cause);
} finally { try {
@@ -574,7 +576,7 @@
transaction.rollback();
}
} finally { try {
- factory.transactionAborted(this);
+ factory.transactionAborted(this, cause);
} finally { try {
abortEnlistedResources();
} finally { try {
Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java 2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java 2009-02-12 17:59:56 UTC (rev 1482)
@@ -56,9 +56,12 @@
private static final Logger logger =
Logger.getLogger(MulgaraInternalTransactionFactory.class.getName());
- /** Set of sessions whose transactions have been rolledback.*/
+ /** Flag indicating current explicit-transaction has been rolledback. */
private boolean isFailed;
+ /** The reason for the failure if {@link #isFailed} is true. */
+ private Throwable failureCause;
+
/** Map of threads to active transactions. */
private final Map<Thread, MulgaraTransaction> activeTransactions;
@@ -78,6 +81,7 @@
super(session, manager);
this.isFailed = false;
+ this.failureCause = null;
this.activeTransactions = new HashMap<Thread, MulgaraTransaction>();
this.autoCommit = true;
this.transactions = new HashSet<MulgaraTransaction>();
@@ -141,7 +145,8 @@
acquireMutex(0, MulgaraTransactionException.class);
try {
if (isFailed) {
- throw new MulgaraTransactionException("Attempting to commit failed session");
+ if (failureCause != null) throw new MulgaraTransactionException("Attempting to commit failed session", failureCause);
+ else throw new MulgaraTransactionException("Attempting to commit failed session");
} else if (!manager.isHoldingWriteLock(session)) {
throw new MulgaraTransactionException(
"Attempting to commit while not the current writing transaction");
@@ -194,6 +199,7 @@
} else if (isFailed) {
explicitXA = null;
isFailed = false;
+ failureCause = null;
setAutoCommit(false);
} else {
throw new MulgaraTransactionException(
@@ -238,6 +244,7 @@
} else if (isFailed) {
// Within failed transaction - cleanup.
isFailed = false;
+ failureCause = null;
}
} else {
if (!manager.isHoldingWriteLock(session)) {
@@ -387,13 +394,14 @@
}
}
- public void transactionAborted(MulgaraTransaction transaction) {
+ public void transactionAborted(MulgaraTransaction transaction, Throwable cause) {
acquireMutex(0, RuntimeException.class);
try {
try {
// Make sure this cleans up the transaction metadata - this transaction is DEAD!
if (!autoCommit && transaction == writeTransaction) {
isFailed = true;
+ failureCause = cause;
}
transactionComplete(transaction);
} catch (Throwable th) {
Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java 2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java 2009-02-12 17:59:56 UTC (rev 1482)
@@ -124,8 +124,8 @@
// 7.6.2.2 requires an XA_RB* exception in the case of 1PC and 7.6.2.5
// implies that HEURRB is not permitted during 2PC - this seems broken
// to me, but that's the spec.
-// throw new XAException(XAException.XA_HEURRB);
- throw new XAException(XAException.XA_RBROLLBACK);
+// throw newXAException(XAException.XA_HEURRB, xa.getRollbackCause());
+ throw newXAException(XAException.XA_RBROLLBACK, xa.getRollbackCause());
} else if (xa.isHeuristicallyCommitted()) {
throw new XAException(XAException.XA_HEURCOM);
}
@@ -191,7 +191,7 @@
break;
case TMSUCCESS:
if (xa.isHeuristicallyRollbacked()) {
- throw new XAException(XAException.XA_RBPROTO);
+ throw newXAException(XAException.XA_RBPROTO, xa.getRollbackCause());
}
break;
case TMSUSPEND: // Should I be tracking the xid's state to ensure
@@ -330,8 +330,9 @@
*/
private void doRollback(MulgaraExternalTransaction xa, Xid xid) throws XAException {
if (xa.isHeuristicallyRollbacked()) {
- logger.warn("Attempted to rollback heuristically rollbacked transaction: " + xa.getHeuristicCode());
- throw new XAException(xa.getHeuristicCode());
+ logger.warn("Attempted to rollback heuristically rollbacked transaction: xa-code=" +
+ xa.getHeuristicCode() + ", reason-string='" + xa.getRollbackCause() + "'");
+ throw newXAException(xa.getHeuristicCode(), xa.getRollbackCause());
} else if (!xa.isRollbacked()) {
xa.rollback(xid);
}
@@ -413,6 +414,12 @@
private DatabaseSession getSession() { return session; }
}
+ private static XAException newXAException(int errorCode, String reason) {
+ XAException xae = new XAException(reason);
+ xae.errorCode = errorCode;
+ return xae;
+ }
+
public static String parseXid(Xid xid) {
return xid.toString();
}
More information about the Mulgara-svn
mailing list