[Mulgara-svn] r132 - in branches/xafix-impl: . jxdata/iTQL/standard_queries src/jar/jrdf/java/org/mulgara/jrdf src/jar/resolver/java/org/mulgara/resolver src/jar/resolver-filesystem/java/org/mulgara/resolver/filesystem src/jar/resolver-gis/java/org/mulgara/resolver/gis src/jar/resolver-lucene/java/org/mulgara/resolver/lucene src/jar/resolver-memory/java/org/mulgara/resolver/memory src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype src/jar/resolver-prefix/java/org/mulgara/resolver/prefix src/jar/resolver-relational/java/org/mulgara/resolver/relational src/jar/resolver-store/java/org/mulgara/resolver/store src/jar/resolver-test/java/org/mulgara/resolver/test src/jar/resolver-url/java/org/mulgara/resolver/url src/jar/resolver-view/java/org/mulgara/resolver/view src/jar/resolver-xsd/java/org/mulgara/resolver/xsd

andrae at mulgara.org andrae at mulgara.org
Thu Nov 16 05:39:42 UTC 2006


Author: andrae
Date: 2006-11-15 23:39:41 -0600 (Wed, 15 Nov 2006)
New Revision: 132

Modified:
   branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult17.txt
   branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult18.txt
   branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult3.txt
   branches/xafix-impl/log4j-conf.xml
   branches/xafix-impl/src/jar/jrdf/java/org/mulgara/jrdf/LocalJRDFSession.java
   branches/xafix-impl/src/jar/resolver-filesystem/java/org/mulgara/resolver/filesystem/FileSystemResolver.java
   branches/xafix-impl/src/jar/resolver-gis/java/org/mulgara/resolver/gis/ReadOnlyGISResolver.java
   branches/xafix-impl/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java
   branches/xafix-impl/src/jar/resolver-memory/java/org/mulgara/resolver/memory/MemoryResolver.java
   branches/xafix-impl/src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype/NodeTypeResolver.java
   branches/xafix-impl/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/PrefixResolver.java
   branches/xafix-impl/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolver.java
   branches/xafix-impl/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolver.java
   branches/xafix-impl/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolver.java
   branches/xafix-impl/src/jar/resolver-url/java/org/mulgara/resolver/url/URLResolver.java
   branches/xafix-impl/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolver.java
   branches/xafix-impl/src/jar/resolver-xsd/java/org/mulgara/resolver/xsd/XSDResolver.java
   branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/CacheResolver.java
   branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
   branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
   branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/InternalResolver.java
   branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java
   branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
   branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/StatusFormat.java
   branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/TransactionalAnswer.java
Log:
This update almost finishes this increment - passes all resolver-test's and
jxunit/standard_queries' tests.
However it will be important for this increment to pass all non-jrdf tests
before I move on to the final increment prior to alpha-release.

Note: Many tests fail simply because they check error conditions, and the text
in the exceptions thrown by a failed transaction has changed.



Modified: branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult17.txt
===================================================================
--- branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult17.txt	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult17.txt	2006-11-16 05:39:41 UTC (rev 132)
@@ -1,4 +1,4 @@
 ItqlInterpreter error - org.mulgara.query.QueryException: Could not commit insert
 Caused by: (QueryException) Could not commit insert
-Caused by: (QueryException) javax.transaction.RollbackException: null
-Caused by: (QueryException) rmi://localhost/server1#nomodelexistswiththisname is not a Model
+Caused by: (QueryException) org.mulgara.resolver.MulgaraTransactionException: Failed transaction finalised. (ROLLBACK)
+Caused by: (QueryException) @server@#nomodelexistswiththisname is not a Model

Modified: branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult18.txt
===================================================================
--- branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult18.txt	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult18.txt	2006-11-16 05:39:41 UTC (rev 132)
@@ -1,5 +1,5 @@
-ItqlInterpreter error - org.mulgara.query.QueryException: Error ending previous query
-Caused by: (QueryException) Error ending previous query
-Caused by: (QueryException) javax.transaction.RollbackException: null
+ItqlInterpreter error - org.mulgara.query.QueryException: Query failed
+Caused by: (QueryException) Query failed
+Caused by: (QueryException) org.mulgara.resolver.MulgaraTransactionException: Failed transaction finalised. (ROLLBACK)
 Caused by: (QueryException) Error resolving [$s $p $o $_from] from mailto:foo at bar.com
 Caused by: (QueryException) Unable to extract hostname from: mailto:foo at bar.com

Modified: branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult3.txt
===================================================================
--- branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult3.txt	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/jxdata/iTQL/standard_queries/queryResult3.txt	2006-11-16 05:39:41 UTC (rev 132)
@@ -1,5 +1,5 @@
-ItqlInterpreter error - org.mulgara.query.QueryException: Error ending previous query
-Caused by: (QueryException) Error ending previous query
-Caused by: (QueryException) javax.transaction.RollbackException: null
+ItqlInterpreter error - org.mulgara.query.QueryException: Query failed
+Caused by: (QueryException) Query failed
+Caused by: (QueryException) org.mulgara.resolver.MulgaraTransactionException: Failed transaction finalised. (ROLLBACK)
 Caused by: (QueryException) Error resolving [$pmid http://mulgara.org/mulgara/Document#subject "Birds" $_from] from @server@#badmodel
 Caused by: (QueryException) @server@#badmodel is not a Model

Modified: branches/xafix-impl/log4j-conf.xml
===================================================================
--- branches/xafix-impl/log4j-conf.xml	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/log4j-conf.xml	2006-11-16 05:39:41 UTC (rev 132)
@@ -51,9 +51,9 @@
   </appender>
 
   <!-- (Insert category elements here) -->
-  <!--
+<!--
   <category name="org.mulgara.resolver.MulgaraTransaction">
-    <priority value="debug"/>
+    <priority value="info"/>
   </category>
   <category name="org.mulgara.resolver.TransactionalAnswer">
     <priority value="debug"/>

Modified: branches/xafix-impl/src/jar/jrdf/java/org/mulgara/jrdf/LocalJRDFSession.java
===================================================================
--- branches/xafix-impl/src/jar/jrdf/java/org/mulgara/jrdf/LocalJRDFSession.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/jrdf/java/org/mulgara/jrdf/LocalJRDFSession.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -49,6 +49,6 @@
  *
  * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
  */
-public interface LocalJRDFSession extends LocalSession, JRDFSession {
+public interface LocalJRDFSession extends JRDFSession {
 
 }

Modified: branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/CacheResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/CacheResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/CacheResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -225,4 +225,6 @@
 
     return temporaryResolver;
   }
+
+  public void abort() {}
 }

Modified: branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
===================================================================
--- branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -34,6 +34,7 @@
 import java.net.URISyntaxException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -67,6 +68,8 @@
 import org.mulgara.resolver.spi.SymbolicTransformation;
 import org.mulgara.resolver.spi.SymbolicTransformationContext;
 import org.mulgara.resolver.spi.SystemResolver;
+import org.mulgara.resolver.spi.SystemResolverFactory;
+import org.mulgara.resolver.spi.TuplesWrapperStatements;
 import org.mulgara.resolver.view.ViewMarker;
 import org.mulgara.resolver.view.SessionView;
 import org.mulgara.store.nodepool.NodePool;
@@ -128,6 +131,7 @@
   private final Map systemModelCacheMap = new WeakHashMap();
 
   /** Resolver used for accessing the system model (<code>#</code>).  */
+  protected SystemResolverFactory systemResolverFactory;
   protected SystemResolver systemResolver;
 
   /** The transaction associated with these operations */
@@ -178,6 +182,7 @@
     this.temporaryResolverFactory   = temporaryResolverFactory;
     this.symbolicTransformationList = symbolicTransformationList;
     this.isWriting                  = isWriting;
+    this.systemResolverFactory      = systemResolverFactory;
 
     this.cachedModelSet             = new HashSet();
     this.changedCachedModelSet      = new HashSet();
@@ -905,9 +910,7 @@
     if (!cachedModelSet.isEmpty()) {
       try {
         Resolver temporaryResolver =
-          temporaryResolverFactory.newResolver(true,
-                                               operationContext.getSystemResolver(),
-                                               operationContext.getSystemResolver());
+          temporaryResolverFactory.newResolver(true, systemResolver, systemResolver);
         for (Iterator i = cachedModelSet.iterator(); i.hasNext();) {
           LocalNode modelLocalNode = (LocalNode) i.next();
           long model = modelLocalNode.getValue();
@@ -916,9 +919,7 @@
             // Write back the modifications to the original model
             try {
               Resolver resolver =
-                findResolverFactory(model).newResolver(true,
-                                                       operationContext.getSystemResolver(),
-                                                       operationContext.getSystemResolver());
+                findResolverFactory(model).newResolver(true, systemResolver, systemResolver);
               Variable s = new Variable("s");
               Variable p = new Variable("p");
               Variable o = new Variable("o");
@@ -949,20 +950,25 @@
   }
 
   public void abort() {
-    Iterator i = enlistedResolverMap().valueSet();
+    Iterator i = enlistedResolverMap.values().iterator();
     while (i.hasNext()) {
       ((Resolver)i.next()).abort();
     }
-    this.clear();
+    try {
+      this.clear();
+    } catch (QueryException eq) {
+      throw new IllegalStateException("Error aborting OperationContext", eq);
+    }
   }
 
   public void initiate(MulgaraTransaction transaction) throws QueryException {
-    this.transaction = transaction;
-    this.systemResolver = systemResolverFactory.newResolver(isWriting);
     try {
+      this.transaction = transaction;
+      this.systemResolver = systemResolverFactory.newResolver(isWriting);
       transaction.enlist(systemResolver);
     } catch (Exception e) {
-      throw new QueryException("Unable to enlist systemResolver:" + resolver + " into transaction", e);
+      throw new QueryException("Unable to enlist systemResolver:" + 
+          systemResolver + " into transaction", e);
     }
   }
 }

Modified: branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
===================================================================
--- branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -75,7 +75,7 @@
  *
  * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
  */
-class DatabaseSession implements Session, LocalSession {
+class DatabaseSession implements Session {
   public static final boolean ASSERT_STATEMENTS = true;
   public static final boolean DENY_STATEMENTS = false;
 
@@ -107,7 +107,7 @@
 
   private final DatabaseMetadata metadata;
 
-  private final DatabaseOperationContext operationContext;
+  private DatabaseOperationContext operationContext;
 
   /** Security adapters this instance should enforce. */
   private final List securityAdapterList;
@@ -127,9 +127,6 @@
   /** Source of transactions.  */
   private final MulgaraTransactionManager transactionManager;
 
-  /** Session transaction */
-  private MulgaraTransaction transaction;
-
   /** The name of the rule loader to use */
   private String ruleLoaderClassName;
 
@@ -139,7 +136,11 @@
   /** The registered {@link ContentHandler} instances.  */
   private ContentHandlerManager contentHandlers;
 
+  /** The temporary model type-URI. */
+  private final URI temporaryModelTypeURI;
 
+  private boolean autoCommit;
+
   /**
    * Construct a database session.
    *
@@ -238,10 +239,9 @@
     this.metadata                   = metadata;
     this.contentHandlers            = contentHandlers;
     this.cachedResolverFactorySet   = cachedResolverFactorySet;
+    this.temporaryModelTypeURI      = temporaryModelTypeURI;
     this.ruleLoaderClassName        = ruleLoaderClassName;
 
-    this.transaction                = null;
-    this.opState                    = FINISH;
     this.operationContext           = null;
     if (logger.isDebugEnabled()) {
       logger.debug("Constructed DatabaseSession");
@@ -391,7 +391,7 @@
 
     // Evaluate the query
     QueryOperation queryOperation = new QueryOperation(query, this);
-    execute(queryOperation, "Failed query");
+    execute(queryOperation, "Query failed");
     return queryOperation.getAnswer();
   }
 
@@ -530,17 +530,30 @@
     if (logger.isInfoEnabled()) {
       logger.info("setAutoCommit(" + autoCommit + ") called.");
     }
-    transactionManager.setAutoCommit(this, autoCommit);
+    try {
+      transactionManager.setAutoCommit(this, autoCommit);
+      this.autoCommit = autoCommit;
+    } catch (MulgaraTransactionException em) {
+      throw new QueryException("Error setting autocommit", em);
+    }
   }
 
   public void commit() throws QueryException {
     logger.info("Committing transaction");
-    transactionManager.explicitCommit(this);
+    try {
+      transactionManager.commit(this);
+    } catch (MulgaraTransactionException em) {
+      throw new QueryException("Error performing commit", em);
+    }
   }
 
   public void rollback() throws QueryException {
     logger.info("Rollback transaction");
-    transactionManager.explicitRollback(this);
+    try {
+      transactionManager.rollback(this);
+    } catch (MulgaraTransactionException em) {
+      throw new QueryException("Error performing rollback", em);
+    }
   }
 
   public void close() throws QueryException {
@@ -569,23 +582,6 @@
     }
   }
 
-  //
-  // Transaction control methods.  Implements LocalSession.
-  //
-
-  public ResolverSession getResolverSession() {
-    assert operationContext != null;
-    return operationContext.getSystemResolver();
-  }
-
-  //
-  // Private accessors intended only for DatabaseOperationContext
-  //
-
-  MulgaraTransaction getTransaction() {
-    return transaction;
-  }
-
   /**
    * Backup all the data on the specified server to a URI or an output stream.
    * The database is not changed by this method.
@@ -640,22 +636,15 @@
    */
   private void execute(Operation operation, String errorString) throws QueryException
   {
-    // Clear previous transaction.  FIXME: This won't be necessary once we
-    // support overlapping transactions.
-    if (autoCommit) {
-      newOperationContext(operation.isWriteOperation());
-      transaction = null;
-    }
-    // FIXME: This currently always initiates transaction - eventually manager
-    // will handle begin vs. resume.
-    if (transaction == null) {
-      transaction = transactionManager.getTransaction(this, operation.isWriteOperation());
-    }
-
-    //
-    // activate needs to worry about resume here.
-    //
     try {
+      // Clear previous transaction.  FIXME: This won't be necessary once we
+      // support overlapping transactions.
+      if (autoCommit) {
+        newOperationContext(operation.isWriteOperation());
+      }
+
+      MulgaraTransaction transaction =
+          transactionManager.getTransaction(this, operation.isWriteOperation());
       transaction.execute(operation, resolverSessionFactory, metadata);
     } catch (MulgaraTransactionException em) {
       throw new QueryException(errorString, em);
@@ -663,7 +652,7 @@
   }
 
   // !!FIXME: needs to be updated to 1-N
-  public OperationContext newOperationContext(boolean writing) {
+  public DatabaseOperationContext newOperationContext(boolean writing) throws QueryException {
     if (operationContext != null) {
       operationContext.clear();
     }
@@ -676,7 +665,6 @@
                              securityAdapterList,
                              temporaryModelTypeURI,
                              temporaryResolverFactory,
-                             transactionManager,
                              symbolicTransformationList,
                              systemResolverFactory,
                              writing

Modified: branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/InternalResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/InternalResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/InternalResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -289,4 +289,8 @@
         new SingletonStatements(model, rdfType, modelType),
         present);
   }
+
+  public void abort() {
+    resolver.abort();
+  }
 }

Modified: branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java
===================================================================
--- branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -27,7 +27,7 @@
 
 // Local packages
 import org.mulgara.resolver.spi.DatabaseMetadata;
-import org.mulgara.resolver.spi.Resolver;
+import org.mulgara.resolver.spi.EnlistableResource;
 import org.mulgara.resolver.spi.ResolverSessionFactory;
 
 import org.mulgara.query.TuplesException;
@@ -65,7 +65,7 @@
     Logger.getLogger(MulgaraTransaction.class.getName());
 
   private MulgaraTransactionManager manager;
-  private OperationContext context;
+  private DatabaseOperationContext context;
 
   private Transaction transaction;
   private Thread currentThread;
@@ -80,9 +80,10 @@
   private int rollback;
   private Throwable rollbackCause;
 
-  public MulgaraTransaction(MulgaraTransactionManager manager, OperationContext context)
+  public MulgaraTransaction(MulgaraTransactionManager manager, DatabaseOperationContext context)
       throws Exception {
-    report("Creating Transaction");
+//    report("Creating Transaction");
+    errorReport("Creating Transaction");
     try {
       if (manager == null) {
         throw new IllegalArgumentException("Manager null in MulgaraTransaction");
@@ -121,6 +122,7 @@
       }
       
       if (manager == null) {
+        errorReport("Attempt to activate terminated transaction");
         throw new MulgaraTransactionException("Attempt to activate terminated transaction");
       }
 
@@ -166,12 +168,13 @@
     }
   }
 
-  // Do I want to check for currentThread here?  Do I want a seperate check() method to 
-  // cover precondition checks against currentThread?
+  // Note: The transaction is often not be activated when this is called.
+  //       This occurs when setting autocommit off, as this creates and
+  //       references a transaction object that won't be started/activated
+  //       until it is first used.
   void reference() throws MulgaraTransactionException {
     report("Referencing Transaction");
     try {
-      checkActivated();
       using++;
     } finally {
       report("Referenced Transaction");
@@ -243,7 +246,7 @@
       logger.warn("Cascading error, transaction already rolled back", cause);
       logger.warn("Cascade error, expected initial cause", rollbackCause);
 
-      return new MulgaraTransactionException("Transaction already in rollback", cause)
+      return new MulgaraTransactionException("Transaction already in rollback", cause);
     }
 
     try {
@@ -257,6 +260,7 @@
       return new MulgaraTransactionException("Transaction in Rollback", cause);
     } catch (Throwable th) {
       abortTransaction("Failed to rollback normally", th);
+      throw new MulgaraTransactionException("Abort failed to throw exception", th);
     }
   }
 
@@ -275,7 +279,7 @@
     }
   }
 
-  private void startTransaction() throws MulgaraTransactioinException {
+  private void startTransaction() throws MulgaraTransactionException {
     report("Initiating transaction");
     transaction = manager.transactionStart(this);
     try {
@@ -285,7 +289,7 @@
     }
   }
 
-  private void resumeTransaction throws MulgaraTransactionException {
+  private void resumeTransaction() throws MulgaraTransactionException {
     report("Resuming transaction");
     try {
       manager.transactionResumed(this, transaction);
@@ -310,21 +314,27 @@
   }
 
   private void terminateTransaction() throws MulgaraTransactionException {
-    report("Terminating Transaction: " + rollback);
+//    report("Terminating Transaction: " + rollback);
+    errorReport("Terminating Transaction: " + rollback);
     try {
       switch (rollback) {
         case NO_ROLLBACK:
           report("Completing Transaction");
-          transaction.commit();
-          transaction = null;
+          try {
+            transaction.commit();
+            transaction = null;
+          } catch (Throwable th) {
+            implicitRollback(th);
+            terminateTransaction();
+          }
           break;
         case IMPLICIT_ROLLBACK:
           report("Completing Implicitly Failed Transaction");
           // Check that transaction is cleaned up.
           throw new MulgaraTransactionException(
-              "Failed transaction finalised with ROLLBACK", rollbackCause);
+              "Failed transaction finalised. (ROLLBACK)", rollbackCause);
         case EXPLICIT_ROLLBACK:
-          report("Completing Explicitly Failed Transaction");
+          report("Completing explicitly failed transaction (ROLLBACK)");
           // Check that transaction is cleaned up.
           break;
       }
@@ -333,8 +343,13 @@
       manager = null;
       inuse = 0;
       using = 0;
-      context.clear();
-      report("Terminated transaction");
+      try {
+        context.clear();
+      } catch (QueryException eq) {
+        throw new MulgaraTransactionException("Error clearing context", eq);
+      } finally {
+        report("Terminated transaction");
+      }
     }
   }
 
@@ -349,7 +364,7 @@
     // can't rollback normally if we can't resume!  The call to
     // context.abort() is an escape hatch we use to abort the 
     // current phase behind the scenes.
-    logger.error(errorMessage " - Aborting", th);
+    logger.error(errorMessage + " - Aborting", th);
     try {
       manager.transactionAborted(this);
     } finally {
@@ -393,17 +408,13 @@
     // MulgaraTransactionManager!
   }
 
-  Transaction getTransaction() {
-    return transaction;
-  }
-
   protected void finalize() {
     report("GC-finalize");
     if (inuse != 0 || using != 0) {
-      logger.error("Referernce counting error in transaction, inuse=" + inuse + ", using=" + using);
+      errorReport("Referernce counting error in transaction");
     }
     if (manager != null || transaction != null) {
-      logger.error("Transaction not terminated properly");
+      errorReport("Transaction not terminated properly");
     }
   }
 
@@ -412,14 +423,14 @@
   //
 
   private void checkActivated() throws MulgaraTransactionException {
-    if (!currentThread.equals(Thread.currentThread()) {
+    if (!currentThread.equals(Thread.currentThread())) {
       throw new MulgaraTransactionException("Concurrent access attempted to transaction: Transaction has NOT been rolledback.");
     } else if (inuse < 1) {
       throw implicitRollback(
           new MulgaraTransactionException("Mismatched activate/deactivate.  inuse < 1: " + inuse));
     } else if (using < 0) {
       throw implicitRollback(
-        throw new MulgaraTransactionException("Reference Failure.  using < 0: " + using));
+          new MulgaraTransactionException("Reference Failure.  using < 0: " + using));
     }
   }
 
@@ -436,4 +447,9 @@
           ", inuse=" + inuse + ", using=" + using);
     }
   }
+
+  private void errorReport(String desc) {
+    logger.error(desc + ": " + System.identityHashCode(this) +
+        ", inuse=" + inuse + ", using=" + using, new Throwable());
+  }
 }

Modified: branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
===================================================================
--- branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -19,7 +19,10 @@
 
 // Java2 packages
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
@@ -91,8 +94,6 @@
 
   private TransactionManager transactionManager;
 
-  private Object writeLockMutex;
-
   public MulgaraTransactionManager(TransactionManagerFactory transactionManagerFactory) {
     this.currentWritingSession = null;
     this.userTransaction = null;
@@ -103,7 +104,6 @@
     this.activeTransactions = new HashMap();
 
     this.transactionManager = transactionManagerFactory.newTransactionManager();
-    this.writeLockMutex = new Object();
   }
 
   /**
@@ -123,21 +123,23 @@
     } 
 
     // FIXME: Remove this once we go to 1-N.
-    if (sessions.contains(session)) {
-      throw MulgaraTransactionException("Multiple Transactions started per session");
+    if (sessions.containsValue(session)) {
+      throw new MulgaraTransactionException("Multiple Transactions started per session");
     }
 
-    if (write) {
-      obtainWriteLock(session);
-    }
-
+    try {
+      if (write) {
+        // Note: obtainWriteLock initiates a new transaction and stores it in userTransaction.
+        sessions.put(obtainWriteLock(session), session);
+        return userTransaction;
+      } else {
 //    FIXME: Need to finish 1-N DS-OC and provide this method - should really be newOperationContext.
-    try {
-      MulgaraTransaction transaction =
-          new MulgaraTransaction(this, session.newOperationContext(write));
-      sessions.put(transaction, session);
+        MulgaraTransaction transaction =
+            new MulgaraTransaction(this, session.newOperationContext(false));
+        sessions.put(transaction, session);
 
-      return transaction;
+        return transaction;
+      }
     } catch (MulgaraTransactionException em) {
       throw em;
     } catch (Exception e) {
@@ -146,26 +148,38 @@
   }
 
 
-  private synchronized void obtainWriteLock(Session session)
+  private synchronized MulgaraTransaction obtainWriteLock(DatabaseSession session)
       throws MulgaraTransactionException {
     while (currentWritingSession != null) {
       try {
-        writeLockMutex.wait();
+        this.wait();
       } catch (InterruptedException ei) {
         throw new MulgaraTransactionException("Interrupted while waiting for write lock", ei);
       }
     }
-    currentWritingSession = session;
+
+    try {
+      currentWritingSession = session;
+      userTransaction = new MulgaraTransaction(this, session.newOperationContext(true));
+      return userTransaction;
+    } catch (MulgaraTransactionException em) {
+      releaseWriteLock();
+      throw em;
+    } catch (Throwable th) {
+      releaseWriteLock();
+      throw new MulgaraTransactionException("Error while obtaining write-lock", th);
+    }
   }
 
   private synchronized void releaseWriteLock() {
+    // FIXME:should check here that it's the correct thread calling release.
     currentWritingSession = null;
     userTransaction = null;
-    writeLockMutex.notify();
+    this.notify();
   }
 
 
-  public synchronized void commit(Session session) throws MulgaraTransactionException {
+  public synchronized void commit(DatabaseSession session) throws MulgaraTransactionException {
     if (failedSessions.contains(session)) {
       throw new MulgaraTransactionException("Attempting to commit failed exception");
     } else if (session != currentWritingSession) {
@@ -183,21 +197,21 @@
    * This 
    * This needs to be distinguished from an implicit rollback triggered by failure.
    */
-  public synchronized void rollback(Session session) throws MulgaraTransactionException {
+  public synchronized void rollback(DatabaseSession session) throws MulgaraTransactionException {
     if (session == currentWritingSession) {
       try {
         userTransaction.explicitRollback();
-        finalizeTransaction();
+        userTransaction.completeTransaction();
       } finally {
         failedSessions.add(currentWritingSession);
         userTransaction = null;
         currentWritingSession = null;
         releaseWriteLock();
-        setAutoCommit(false);
+        setAutoCommit(session, false);
       }
-    } else if (failedSessions.contains(session) {
+    } else if (failedSessions.contains(session)) {
       failedSessions.remove(session);
-      setAutoCommit(false);
+      setAutoCommit(session, false);
     } else {
       throw new MulgaraTransactionException(
           "Attempt to rollback while not in the current writing transaction");
@@ -216,6 +230,7 @@
         if (session == currentWritingSession) {
           // Within active transaction - commit and finalise.
           try {
+            userTransaction.dereference();
             userTransaction.completeTransaction();
           } finally {
             releaseWriteLock();
@@ -235,28 +250,36 @@
       } else {
         // AutoCommit on -> off == Start new transaction.
         userTransaction = getTransaction(session, true);
-        currentWritingSession = session;
+        userTransaction.reference();
       }
     }
   }
 
   public synchronized void terminateCurrentTransactions(Session session)
       throws MulgaraTransactionException {
-    if (failedSessions.contains(session) {
+    if (failedSessions.contains(session)) {
       failedSessions.remove(session);
       return;
     }
 
-    Throwable error;
+    Throwable error = null;
     try {
       if (session == currentWritingSession) {
-        logger.error("Terminating session while holding writelock");
+        logger.error("Terminating session while holding writelock:" + session +
+        ":" + currentWritingSession + ": " + userTransaction);
         userTransaction.execute(new AnswerOperation() {
             public void execute() {
-              userTransaction.implicitRollback(
-                new MulgaraTransactionException("Terminating session while holding writelock"));
+              try {
+                logger.warn("Checkpoint 1");
+                userTransaction.implicitRollback(
+                  new MulgaraTransactionException("Terminating session while holding writelock"));
+                logger.warn("Checkpoint 2");
+              } catch (Exception e) {
+                throw new IllegalStateException("Error in rollback", e);
+              }
             }
         });
+        logger.warn("Checkpoint 3");
       }
     } catch (Throwable th) {
       error = th;
@@ -268,11 +291,24 @@
       while (i.hasNext()) {
         MulgaraTransaction transaction = (MulgaraTransaction)i.next();
         logger.error("Active transaction during session termination");
-        transaction.implicitRollback(new MulgaraTransactionException(
-            "Terminating session during active transaction");
+        Throwable th = transaction.implicitRollback(
+            new MulgaraTransactionException("Terminating session during active transaction"));
+        if (error ==  null) {
+          error = th;
+        }
         transaction.completeTransaction();
       }
     }
+
+    // Do we need to finish here by calling abort() on the transaction?
+
+    if (error != null) {
+      if (error instanceof MulgaraTransactionException) {
+        throw (MulgaraTransactionException)error;
+      } else {
+        throw new MulgaraTransactionException("Aborting session on close", error);
+      }
+    }
   }
 
   //
@@ -301,7 +337,7 @@
     }
   }
 
-  public synchronized void transactionResumed(MulgaraTransaction transaction) 
+  public synchronized void transactionResumed(MulgaraTransaction transaction, Transaction jtaXA) 
       throws MulgaraTransactionException {
     if (activeTransactions.get(Thread.currentThread()) != null) {
       throw new MulgaraTransactionException(
@@ -311,7 +347,7 @@
     }
     
     try {
-      transactionManager.resume(transaction.getTransaction());
+      transactionManager.resume(jtaXA);
       activeTransactions.put(Thread.currentThread(), transaction);
     } catch (Exception e) {
       throw new MulgaraTransactionException("Resume Failed", e);
@@ -347,9 +383,15 @@
     }
 
     activeTransactions.remove(Thread.currentThread());
+    Session session = (Session)sessions.get(transaction);
     sessions.remove(transaction);
+    transactions.remove(session);
   }
 
+  public synchronized void transactionFailed(MulgaraTransaction transaction) {
+    // No specific behaviour required here.
+  }
+
   public synchronized void transactionAborted(MulgaraTransaction transaction) {
     try {
       // Make sure this cleans up the transaction metadata - this transaction is DEAD!

Modified: branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/StatusFormat.java
===================================================================
--- branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/StatusFormat.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/StatusFormat.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -88,6 +88,7 @@
    *
    * @param transactionManager  the transaction manager
    */
+   /*
   public static String formatStatus(MulgaraTransactionManager transactionManager)
   {
     try {
@@ -97,4 +98,5 @@
       return e.getMessage();
     }
   }
+  */
 }

Modified: branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/TransactionalAnswer.java
===================================================================
--- branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/TransactionalAnswer.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver/java/org/mulgara/resolver/TransactionalAnswer.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -57,6 +57,8 @@
 
   private MulgaraTransaction transaction;
 
+  private boolean closing;
+
   public TransactionalAnswer(MulgaraTransaction transaction, Answer answer) throws TuplesException {
     try {
       report("Creating Answer");
@@ -68,6 +70,7 @@
       }
 
       this.answer = answer;
+      this.closing = false;
       this.transaction = transaction;
       transaction.reference();
 
@@ -106,8 +109,13 @@
 
   public void close() throws TuplesException {
     report("Closing Answer");
-    notClosed();
+    if (closing) {
+      report("Deferring close to enclosing call");
+      return;
+    }
     try {
+      notClosed();
+      closing = true;
       transaction.execute(new AnswerOperation() {
           public void execute() throws TuplesException {
             answer.close();
@@ -120,6 +128,7 @@
         });
     } finally {
       // !!FIXME: Note - We will need to add checks for null to all operations.
+      closing = false;
       transaction = null;
       answer = null;    // Note this permits the gc of the answer.
       report("Closed Answer");
@@ -229,7 +238,7 @@
   public void finalize() {
     report("GC-finalizing");
     if (transaction != null) {
-      logger.error("TransactionalAnswer not closed");
+      logger.warn("TransactionalAnswer not closed");
     }
   }
 

Modified: branches/xafix-impl/src/jar/resolver-filesystem/java/org/mulgara/resolver/filesystem/FileSystemResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-filesystem/java/org/mulgara/resolver/filesystem/FileSystemResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-filesystem/java/org/mulgara/resolver/filesystem/FileSystemResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -474,4 +474,6 @@
       throw new ResolverException("Invalid URI", eu);
     }
   }
+
+  public void abort() {}
 }

Modified: branches/xafix-impl/src/jar/resolver-gis/java/org/mulgara/resolver/gis/ReadOnlyGISResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-gis/java/org/mulgara/resolver/gis/ReadOnlyGISResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-gis/java/org/mulgara/resolver/gis/ReadOnlyGISResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -222,4 +222,9 @@
      */
     return resolver.resolve(constraint);
   }
+
+  public void abort() {
+    resolver.abort();
+  }
+
 }

Modified: branches/xafix-impl/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -347,4 +347,6 @@
   private FullTextStringIndex openFullTextStringIndex(long model) throws FullTextStringIndexException {
     return new FullTextStringIndex(new File(directory, Long.toString(model)).toString(), "gn"+model );
   }
+
+  public void abort() {}
 }

Modified: branches/xafix-impl/src/jar/resolver-memory/java/org/mulgara/resolver/memory/MemoryResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-memory/java/org/mulgara/resolver/memory/MemoryResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-memory/java/org/mulgara/resolver/memory/MemoryResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -49,6 +49,7 @@
 import org.mulgara.store.tuples.AbstractTuples;
 import org.mulgara.store.tuples.Tuples;
 import org.mulgara.store.xa.XAResolverSession;
+import org.mulgara.store.xa.SimpleXAResourceException;
 
 /**
  * Resolves constraints in models stored on the Java heap.
@@ -380,4 +381,18 @@
 
     return buffer.toString();
   }
+
+  public void abort() {
+    if (xaResolverSession != null) {
+      try {
+        try {
+          xaResolverSession.rollback();
+        } finally {
+          xaResolverSession.release();
+        }
+      } catch (SimpleXAResourceException es) {
+        throw new IllegalStateException("Error aborting resolver session", es);
+      }
+    }
+  }
 }

Modified: branches/xafix-impl/src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype/NodeTypeResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype/NodeTypeResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype/NodeTypeResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -371,4 +371,5 @@
     // no-op
   }
 
+  public void abort() {}
 }

Modified: branches/xafix-impl/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/PrefixResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/PrefixResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/PrefixResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -336,4 +336,5 @@
     // no-op
   }
 
+  public void abort() {}
 }

Modified: branches/xafix-impl/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -338,4 +338,9 @@
       throw new ResolverException("Invalid URI", eu);
     }
   }
+
+  public void abort() {
+    // We need to clear the JDBC connections here, but we don't have a handle on
+    // the Resolutions.
+  }
 }

Modified: branches/xafix-impl/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -56,6 +56,7 @@
 import org.mulgara.store.tuples.Tuples;
 import org.mulgara.store.tuples.TuplesOperations;
 import org.mulgara.store.xa.SimpleXAResource;
+import org.mulgara.store.xa.SimpleXAResourceException;
 import org.mulgara.store.xa.XAResolverSession;
 import org.mulgara.store.xa.XAStatementStore;
 
@@ -527,11 +528,23 @@
   }
 
 
-  // FIXME: Need to propagate to other resolvers.
   public void abort() {
-    statementStore.rollback();
-    xaResolverSession.rollback();
-    statementStore.release();
-    xaResolverSession.release();
+    try {
+      try {
+        statementStore.rollback();
+      } finally {
+        try {
+          xaResolverSession.rollback();
+        } finally {
+          try {
+            statementStore.release();
+          } finally {
+            xaResolverSession.release();
+          }
+        }
+      }
+    } catch (SimpleXAResourceException es) {
+      throw new IllegalStateException("Failed to Abort store", es);
+    }
   }
 }

Modified: branches/xafix-impl/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -137,4 +137,6 @@
       throw new QueryException("Failed to resolve constraint", et);
     }
   }
+
+  public void abort() {}
 }

Modified: branches/xafix-impl/src/jar/resolver-url/java/org/mulgara/resolver/url/URLResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-url/java/org/mulgara/resolver/url/URLResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-url/java/org/mulgara/resolver/url/URLResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -363,4 +363,6 @@
       throw new QueryException("Couldn't read URL " + modelURIReference, e);
     }
   }
+
+  public void abort() {}
 }

Modified: branches/xafix-impl/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -395,4 +395,6 @@
       throw new ResolverException("Invalid URI", eu);
     }
   }
+
+  public void abort() {}
 }

Modified: branches/xafix-impl/src/jar/resolver-xsd/java/org/mulgara/resolver/xsd/XSDResolver.java
===================================================================
--- branches/xafix-impl/src/jar/resolver-xsd/java/org/mulgara/resolver/xsd/XSDResolver.java	2006-11-14 08:33:20 UTC (rev 131)
+++ branches/xafix-impl/src/jar/resolver-xsd/java/org/mulgara/resolver/xsd/XSDResolver.java	2006-11-16 05:39:41 UTC (rev 132)
@@ -452,4 +452,6 @@
       throw new Error("Unsupported constraint element: " + constraintElement);
     }
   }
+
+  public void abort() {}
 }




More information about the Mulgara-svn mailing list