[Mulgara-svn] r569 - branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver
andrae at mulgara.org
andrae at mulgara.org
Wed Nov 21 11:12:45 UTC 2007
Author: andrae
Date: 2007-11-21 05:12:44 -0600 (Wed, 21 Nov 2007)
New Revision: 569
Modified:
branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
Log:
Next increment towards proper handling of rollbacks.
Also includes several interface/compile-error fixes.
Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java 2007-11-21 11:11:27 UTC (rev 568)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java 2007-11-21 11:12:44 UTC (rev 569)
@@ -18,6 +18,13 @@
package org.mulgara.resolver;
// Java 2 enterprise packages
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
// Third party packages
import org.apache.log4j.Logger;
@@ -43,6 +50,9 @@
* @licence Open Software License v3.0
*/
public class MulgaraExternalTransaction implements MulgaraTransaction {
+ private static final Logger logger =
+ Logger.getLogger(MulgaraExternalTransaction.class.getName());
+
private Xid xid;
private Set<EnlistableResource> enlisted;
@@ -53,7 +63,11 @@
private MulgaraExternalTransactionFactory factory;
private DatabaseOperationContext context;
- MulgaraExternalTransaction(MulgaraExternalTransactionFactory resource, OperationContext context) {
+ private boolean hRollback;
+ private int heurCode;
+ private boolean rollback;
+
+ MulgaraExternalTransaction(MulgaraExternalTransactionFactory resource, DatabaseOperationContext context) {
this.factory = factory;
this.context = context;
@@ -61,63 +75,96 @@
this.prepared = new HashSet<EnlistableResource>();
this.committed = new HashSet<EnlistableResource>();
this.rollbacked = new HashSet<EnlistableResource>();
+
+ this.hRollback = false;
+ this.heurCode = 0;
+ this.rollback = false;
}
// We ignore reference counting in external transactions
- void reference() throws MulgaraTransactionException {}
- void dereference() throws MulgaraTransactionException {}
+ public void reference() throws MulgaraTransactionException {}
+ public void dereference() throws MulgaraTransactionException {}
- MulgaraTransactionException abortTransaction(String errorMessage, Throwable cause)
+ public MulgaraTransactionException abortTransaction(String errorMessage, Throwable cause)
throws MulgaraTransactionException {
try {
- if (resource.getStatus() == MulgaraXAResource.ACTIVE) {
- resource.setRollback(cause);
+ for (EnlistableResource resource : enlisted) {
+ try {
+ resource.abort();
+ } catch (Throwable throw_away) {}
}
- for (EnlistableResource resource : resources) {
+ for (EnlistableResource resource : prepared) {
try {
resource.abort();
} catch (Throwable throw_away) {}
}
+
+ return new MulgaraTransactionException(errorMessage, cause);
} finally {
cleanupTransaction();
}
}
+ public void heuristicRollback(String cause) throws MulgaraTransactionException {
+ hRollback = true;
+ try {
+ rollback(xid);
+ } catch (XAException xa) {
+ throw new MulgaraTransactionException("Failed heuristic rollback", xa);
+ } finally {
+ heurCode = heurCode == 0 ? XAException.XA_HEURRB : heurCode;
+ }
+ }
- void execute(Operation operation,
+ public void execute(Operation operation,
ResolverSessionFactory resolverSessionFactory,
DatabaseMetadata metadata) throws MulgaraTransactionException {
- if (resource.getStatus() != MulgaraXAResource.ACTIVE) {
- throw new MulgaraTransactionException("Invalid transactional context : " + resource.getStatus());
- }
+ // FIXME: Do I need to check that this transaction is 'active' ?
try {
operation.execute(context,
context.getSystemResolver(),
resolverSessionFactory,
metadata);
} catch (Throwable th) {
- resource.setRollback(th);
+ try {
+ rollback(xid);
+ } catch (XAException ex) {
+ logger.error("Error in rollback after operation failure", ex);
+ }
throw new MulgaraTransactionException("Operation failed", th);
}
}
- AnswerOperationResult execute(AnswerOperation ao) throws TuplesException {
- if (resource.getStatus() != MulgaraXAResource.ACTIVE) {
- throw new TuplesException("Invalid transactional context : " + resource.getStatus());
- }
+ public AnswerOperationResult execute(AnswerOperation ao) throws TuplesException {
try {
- return ao.execute();
+ ao.execute();
+ return ao.getResult();
} catch (Throwable th) {
- resource.setRollback(th);
+ try {
+ rollback(xid);
+ } catch (XAException ex) {
+ logger.error("Error in rollback after answer-operation failure", ex);
+ }
throw new TuplesException("Request failed", th);
}
}
+ // FIXME: See if we can't rearrange things to allow this to be deleted.
+ public void execute(TransactionOperation to) throws MulgaraTransactionException {
+ throw new MulgaraTransactionException("Not Implemented: shouldn't be required");
+ }
+
public void enlist(EnlistableResource enlistable) throws MulgaraTransactionException {
- if (!resources.contains(enlistable)) {
- XAResource res = enlistable.getXAResource();
- bringUptodate(res);
- resources.add(enlistable);
+ try {
+ if (!enlisted.contains(enlistable)) {
+ enlisted.add(enlistable);
+ XAResource res = enlistable.getXAResource();
+ // FIXME: We need to handle this uptodate operation properly.
+ // bringUptodate(res);
+ res.start(xid, XAResource.TMNOFLAGS);
+ }
+ } catch (XAException ex) {
+ throw new MulgaraTransactionException("Failed to enlist resource", ex);
}
}
@@ -126,7 +173,8 @@
//
void commit(Xid xid) throws XAException {
- for (EnlistableResource er : xa.getEnlistedResources()) {
+ // FIXME: Consider the possiblity prepare failed, or was incomplete.
+ for (EnlistableResource er : prepared) {
er.getXAResource().commit(xid, false);
committed.add(er);
}
@@ -134,15 +182,19 @@
}
boolean isHeuristicallyRollbacked() {
- return false;
+ return hRollback;
}
boolean isHeuristicallyCommitted() {
return false;
}
+ boolean isRollbacked() {
+ return rollback;
+ }
+
void prepare(Xid xid) throws XAException {
- for (EnlistableResource er : xa.getEnlistedResources()) {
+ for (EnlistableResource er : enlisted) {
er.getXAResource().prepare(xid);
prepared.add(er);
}
@@ -151,14 +203,13 @@
void rollback(Xid xid) throws XAException {
try {
+ rollback = true;
Map<EnlistableResource, XAException> rollbackFailed = new HashMap<EnlistableResource, XAException>();
- assert exception != null;
-
- for (EnlistableResource er : xa.getEnlistedResources()) {
+ for (EnlistableResource er : enlisted) {
try {
if (!committed.contains(er)) {
- er.getXAResource().rollback(xid, false);
+ er.getXAResource().rollback(xid);
rollbacked.add(er);
}
} catch (XAException ex) {
@@ -189,7 +240,7 @@
// All these amount to not knowing the result - so we have a hazard
// unless we already know we have a mixed result.
if (heurCode != XAException.XA_HEURMIX) {
- XAException.XA_HEURHAZ;
+ heurCode = XAException.XA_HEURHAZ;
}
break;
case XAException.XA_HEURCOM:
@@ -225,10 +276,6 @@
}
}
- boolean isRollbackOnly() {
- return rollbackOnly;
- }
-
private void cleanupTransaction() {
factory.transactionComplete(this);
}
More information about the Mulgara-svn
mailing list