[Mulgara-svn] r595 - in branches/mgr-73/src/jar: resolver/java/org/mulgara/resolver resolver-store/java/org/mulgara/resolver/store

andrae at mulgara.org andrae at mulgara.org
Tue Dec 4 06:43:40 UTC 2007


Author: andrae
Date: 2007-12-04 00:43:39 -0600 (Tue, 04 Dec 2007)
New Revision: 595

Modified:
   branches/mgr-73/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreXAResource.java
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
Log:
With these small fixes to the rollback code I am now happy with the behaviour of
the external JTA resource when used consistently with my understanding of the
JTA spec - with the exception of isSameRM detailed below.

What isn't tested is non-compliant use of the resource; interaction between
external and internal transactions; and a full end-to-end test using JOTM.

I also suspect that the implementation of isSameRM will fail when performed over
RMI.



Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java	2007-12-04 04:29:12 UTC (rev 594)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java	2007-12-04 06:43:39 UTC (rev 595)
@@ -112,6 +112,7 @@
     suite.addTest(new ExternalTransactionUnitTest("testConcurrentSubqueryQuery"));
     suite.addTest(new ExternalTransactionUnitTest("testExplicitIsolationQuerySingleSession"));
     suite.addTest(new ExternalTransactionUnitTest("testConcurrentExplicitTxn"));
+    suite.addTest(new ExternalTransactionUnitTest("testExplicitRollbackIsolationQuery"));
 
     return suite;
   }
@@ -1162,6 +1163,101 @@
     }
   }
 
+  public void testExplicitRollbackIsolationQuery() throws URISyntaxException {
+    logger.info("testExplicitRollbackIsolationQuery");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session = database.newSession();
+      XAResource roResource = session.getReadOnlyXAResource();
+      XAResource rwResource = session.getXAResource();
+      try {
+        rwResource.start(new TestXid(1), XAResource.TMNOFLAGS);
+        session.createModel(model3URI, null);
+        rwResource.end(new TestXid(1), XAResource.TMSUCCESS);
+        rwResource.commit(new TestXid(1), true);
+
+        rwResource.start(new TestXid(2), XAResource.TMNOFLAGS);
+        session.setModel(model3URI, new ModelResource(fileURI));
+        rwResource.end(new TestXid(2), XAResource.TMSUSPEND);
+
+        roResource.start(new TestXid(3), XAResource.TMNOFLAGS);
+
+        Variable subjectVariable   = new Variable("subject");
+        Variable predicateVariable = new Variable("predicate");
+        Variable objectVariable    = new Variable("object");
+
+        List selectList = new ArrayList(3);
+        selectList.add(subjectVariable);
+        selectList.add(predicateVariable);
+        selectList.add(objectVariable);
+
+        // Evaluate the query
+        Answer answer = session.query(new Query(
+          selectList,                                       // SELECT
+          new ModelResource(model3URI),                      // FROM
+          new ConstraintImpl(subjectVariable,               // WHERE
+                         predicateVariable,
+                         objectVariable),
+          null,                                             // HAVING
+          Arrays.asList(new Order[] {                       // ORDER BY
+            new Order(subjectVariable, true),
+            new Order(predicateVariable, true),
+            new Order(objectVariable, true)
+          }),
+          null,                                             // LIMIT
+          0,                                                // OFFSET
+          new UnconstrainedAnswer()                         // GIVEN
+        ));
+        answer.beforeFirst();
+        assertFalse(answer.next());
+        answer.close();
+
+        roResource.end(new TestXid(3), XAResource.TMSUCCESS);
+        roResource.commit(new TestXid(3), true);
+
+        rwResource.end(new TestXid(2), XAResource.TMFAIL);
+        rwResource.rollback(new TestXid(2));
+
+        roResource.start(new TestXid(4), XAResource.TMNOFLAGS);
+        selectList = new ArrayList(3);
+        selectList.add(subjectVariable);
+        selectList.add(predicateVariable);
+        selectList.add(objectVariable);
+
+        // Evaluate the query
+        answer = session.query(new Query(
+          selectList,                                       // SELECT
+          new ModelResource(model3URI),                      // FROM
+          new ConstraintImpl(subjectVariable,               // WHERE
+                         predicateVariable,
+                         objectVariable),
+          null,                                             // HAVING
+          Arrays.asList(new Order[] {                       // ORDER BY
+            new Order(subjectVariable, true),
+            new Order(predicateVariable, true),
+            new Order(objectVariable, true)
+          }),
+          null,                                             // LIMIT
+          0,                                                // OFFSET
+          new UnconstrainedAnswer()                         // GIVEN
+        ));
+
+        answer.beforeFirst();
+        assertFalse(answer.next());
+        answer.close();
+
+        roResource.end(new TestXid(4), XAResource.TMFAIL);
+        roResource.rollback(new TestXid(4));
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+
   //
   // Internal methods
   //

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-12-04 04:29:12 UTC (rev 594)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java	2007-12-04 06:43:39 UTC (rev 595)
@@ -197,6 +197,10 @@
     return false;
   }
 
+  int getHeuristicCode() {
+    return heurCode;
+  }
+
   boolean isRollbacked() {
     return rollback;
   }
@@ -227,8 +231,8 @@
       }
 
       if (rollbackFailed.isEmpty()) {
-        if (committed.isEmpty()) {        // Clean failure and rollback - rethrow cause
-          // status = ROLLBACK_COMPLETED;
+        if (committed.isEmpty()) {        // Clean failure and rollback
+          return; // SUCCESSFUL ROLLBACK - RETURN
         } else {                          // No rollback-failure, but partial commit
           heurCode = XAException.XA_HEURMIX;
           throw new XAException(heurCode);

Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java	2007-12-04 04:29:12 UTC (rev 594)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java	2007-12-04 06:43:39 UTC (rev 595)
@@ -105,7 +105,7 @@
             xa.prepare(xid);
           } catch (XAException ex) {
             if (ex.errorCode != XAException.XA_RDONLY) {
-              xa.rollback(xid);
+              doRollback(xa, xid);
             }
             throw ex;
           }
@@ -153,7 +153,7 @@
         }
         switch (flags) {
           case TMFAIL:
-            xa.rollback(xid);
+            doRollback(xa, xid);
             break;
           case TMSUCCESS:
             break;
@@ -277,13 +277,23 @@
           throw new XAException(XAException.XAER_NOTA);
         }
 
-        xa.rollback(xid);
+        doRollback(xa, xid);
       } finally {
         releaseMutex();
       }
     }
 
 
+    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());
+      } else if (!xa.isRollbacked()) {
+        xa.rollback(xid);
+      }
+    }
+
+
     public boolean setTransactionTimeout(int seconds) {
       acquireMutex();
       try {

Modified: branches/mgr-73/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreXAResource.java
===================================================================
--- branches/mgr-73/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreXAResource.java	2007-12-04 04:29:12 UTC (rev 594)
+++ branches/mgr-73/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreXAResource.java	2007-12-04 06:43:39 UTC (rev 595)
@@ -367,6 +367,9 @@
 
 
   private void cleanup(String operation) {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Performing cleanup from " + operation);
+    }
     try {
       synchronized(preparing) {
         if (preparing.contains(session)) {




More information about the Mulgara-svn mailing list