[Mulgara-svn] r1057 - branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver

ronald at mulgara.org ronald at mulgara.org
Mon Jul 7 12:54:01 UTC 2008


Author: ronald
Date: 2008-07-07 05:53:59 -0700 (Mon, 07 Jul 2008)
New Revision: 1057

Modified:
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
Log:
Changed scope of transaction factories to be per-session because all operations
are session-scoped anyway. This avoids the need to keep multiple maps in order
to look up the per-session information and avoids the need to pass the session
to all methods. Furthermore, with upcoming changes that rework the timeout
handling we can then completly eliminate the mutexes.


Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java	2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java	2008-07-07 12:53:59 UTC (rev 1057)
@@ -237,10 +237,7 @@
   private final URI temporaryModelTypeURI;
 
   /**
-   * Factory for the {@link #transactionManager}.
-   *
-   * This only reason we hold a reference to this is so that it can be closed
-   * when the database shuts down.
+   * Factory for internal jta TransactionManager's.
    */
   private final TransactionManagerFactory transactionManagerFactory;
 
@@ -513,7 +510,7 @@
     assert this.contentHandlers != null;
 
     // FIXME: Migrate this code inside StringPoolSession.  Pass config to StringPoolSession.
-    this.transactionManager = new MulgaraTransactionManager(transactionManagerFactory);
+    this.transactionManager = new MulgaraTransactionManager();
 
     this.defaultTransactionTimeout = transactionTimeout * 1000L;
     this.defaultIdleTimeout = idleTimeout * 1000L;
@@ -679,6 +676,7 @@
 
     DatabaseSession session = new DatabaseSession(
         transactionManager,
+        transactionManagerFactory,
         unmodifiableSecurityAdapterList,
         unmodifiableSymbolicTransformationList,
         spSessionFactory,
@@ -892,6 +890,7 @@
     try {
       return new DatabaseSession(
         transactionManager,
+        transactionManagerFactory,
         unmodifiableSecurityAdapterList,
         unmodifiableSymbolicTransformationList,
         spSessionFactory,
@@ -922,6 +921,7 @@
     try {
       return new LocalJRDFDatabaseSession(
           transactionManager,
+          transactionManagerFactory,
           unmodifiableSecurityAdapterList,
           unmodifiableSymbolicTransformationList,
           jrdfSessionFactory,
@@ -1146,6 +1146,7 @@
       try {
         return new DatabaseSession(
           transactionManager,
+          transactionManagerFactory,
           Collections.singletonList(
             (SecurityAdapter)new SystemModelSecurityAdapter(metadata.getSystemModelNode())
           ),
@@ -1176,6 +1177,7 @@
       try {
         return new LocalJRDFDatabaseSession(
           transactionManager,
+          transactionManagerFactory,
           Collections.singletonList(
             new SystemModelSecurityAdapter(metadata.getSystemModelNode())
           ),

Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2008-07-07 12:53:59 UTC (rev 1057)
@@ -49,6 +49,7 @@
 import org.mulgara.resolver.spi.*;
 import org.mulgara.rules.*;
 import org.mulgara.server.Session;
+import org.mulgara.transaction.TransactionManagerFactory;
 
 /**
  * A database session.
@@ -112,8 +113,8 @@
   private final MulgaraTransactionManager transactionManager;
 
   private MulgaraTransactionFactory transactionFactory;
-  private MulgaraInternalTransactionFactory internalFactory;
-  private MulgaraExternalTransactionFactory externalFactory;
+  private final MulgaraInternalTransactionFactory internalFactory;
+  private final MulgaraExternalTransactionFactory externalFactory;
 
   /** the default maximum transaction duration */
   private final long defaultTransactionTimeout;
@@ -144,6 +145,8 @@
    *
    * @param transactionManager  the source of transactions for this session,
    *   never <code>null</code>
+   * @param transactionManagerFactory  factory for internal jta transaction-manager
+   *   for this session, never <code>null</code>
    * @param securityAdapterList  {@link List} of {@link SecurityAdapter}s to be
    *   consulted before permitting operations, never <code>null</code>
    * @param symbolicTransformationList  {@link List} of
@@ -180,6 +183,7 @@
    * @throws IllegalArgumentException if any argument is <code>null</code>
    */
   DatabaseSession(MulgaraTransactionManager transactionManager,
+      TransactionManagerFactory transactionManagerFactory,
       List<SecurityAdapter> securityAdapterList,
       List<SymbolicTransformation> symbolicTransformationList,
       ResolverSessionFactory resolverSessionFactory,
@@ -205,6 +209,8 @@
     // Validate parameters
     if (transactionManager == null) {
       throw new IllegalArgumentException("Null 'transactionManager' parameter");
+    } else if (transactionManagerFactory == null) {
+      throw new IllegalArgumentException("Null 'transactionManagerFactory' parameter");
     } else if (securityAdapterList == null) {
       throw new IllegalArgumentException("Null 'securityAdapterList' parameter");
     } else if (symbolicTransformationList == null) {
@@ -256,7 +262,9 @@
     this.ruleLoaderClassName        = ruleLoaderClassName;
 
     this.transactionFactory = null;
-    this.internalFactory = null;
+    this.externalFactory = new MulgaraExternalTransactionFactory(this, transactionManager);
+    this.internalFactory =
+        new MulgaraInternalTransactionFactory(this, transactionManager, transactionManagerFactory);
 
     this.transactionTimeout  = defaultTransactionTimeout;
     this.idleTimeout         = defaultIdleTimeout;
@@ -269,6 +277,7 @@
    * Non-rule version of the constructor.  Accepts all parameters except ruleLoaderClassName.
    */
   DatabaseSession(MulgaraTransactionManager transactionManager,
+      TransactionManagerFactory transactionManagerFactory,
       List<SecurityAdapter> securityAdapterList,
       List<SymbolicTransformation> symbolicTransformationList,
       ResolverSessionFactory resolverSessionFactory,
@@ -281,7 +290,7 @@
       ContentHandlerManager contentHandlers,
       Set<ResolverFactory> cachedResolverFactorySet,
       URI temporaryModelTypeURI) throws ResolverFactoryException {
-    this(transactionManager, securityAdapterList, symbolicTransformationList, resolverSessionFactory,
+    this(transactionManager, transactionManagerFactory, securityAdapterList, symbolicTransformationList, resolverSessionFactory,
         systemResolverFactory, temporaryResolverFactory, resolverFactoryList, externalResolverFactoryMap,
         internalResolverFactoryMap, metadata, contentHandlers, cachedResolverFactorySet,
         temporaryModelTypeURI, 0, 0, null);
@@ -532,7 +541,7 @@
     if (logger.isDebugEnabled()) logger.debug("setAutoCommit(" + autoCommit + ") called.");
     assertInternallyManagedXA();
     try {
-      internalFactory.setAutoCommit(this, autoCommit);
+      internalFactory.setAutoCommit(autoCommit);
     } catch (MulgaraTransactionException em) {
       throw new QueryException("Error setting autocommit", em);
     }
@@ -543,7 +552,7 @@
     logger.debug("Committing transaction");
     assertInternallyManagedXA();
     try {
-      internalFactory.commit(this);
+      internalFactory.commit();
     } catch (MulgaraTransactionException em) {
       throw new QueryException("Error performing commit", em);
     }
@@ -554,7 +563,7 @@
     logger.debug("Rollback transaction");
     assertInternallyManagedXA();
     try {
-      internalFactory.rollback(this);
+      internalFactory.rollback();
     } catch (MulgaraTransactionException em) {
       throw new QueryException("Error performing rollback", em);
     }
@@ -564,11 +573,25 @@
   public void close() throws QueryException {
     logger.debug("Closing session");
     try {
-      transactionManager.closingSession(this);
       transactionFactory = null;
-    } catch (MulgaraTransactionException em2) {
-      logger.error("Error force-closing session", em2);
-      throw new QueryException("Error force-closing session.", em2);
+      externalFactory.closingSession();
+    } catch (MulgaraTransactionException em) {
+      logger.error("Error force-closing session", em);
+      throw new QueryException("Error force-closing session.", em);
+    } finally {
+      try {
+        internalFactory.closingSession();
+      } catch (MulgaraTransactionException em2) {
+        logger.error("Error force-closing session", em2);
+        throw new QueryException("Error force-closing session.", em2);
+      } finally {
+        try {
+          transactionManager.closingSession(this);
+        } catch (MulgaraTransactionException em2) {
+          logger.error("Error force-closing session", em2);
+          throw new QueryException("Error force-closing session.", em2);
+        }
+      }
     }
   }
 
@@ -638,7 +661,7 @@
   private void execute(Operation operation, String errorString) throws QueryException {
     ensureTransactionFactorySelected();
     try {
-      MulgaraTransaction transaction = transactionFactory.getTransaction(this, operation.isWriteOperation());
+      MulgaraTransaction transaction = transactionFactory.getTransaction(operation.isWriteOperation());
       transaction.execute(operation, metadata);
     } catch (MulgaraTransactionException em) {
       logger.debug("Error executing operation: " + errorString, em);
@@ -684,8 +707,8 @@
 
   private void assertInternallyManagedXA() throws QueryException {
     if (transactionFactory == null) {
-      transactionFactory = internalFactory = transactionManager.getInternalFactory();
-    } else if (internalFactory == null) {
+      transactionFactory = internalFactory;
+    } else if (transactionFactory != internalFactory) {
       throw new QueryException("Attempt to use internal transaction control in externally managed session");
     }
   }
@@ -693,8 +716,8 @@
 
   private void assertExternallyManagedXA() throws QueryException {
     if (transactionFactory == null) {
-      transactionFactory = externalFactory = transactionManager.getExternalFactory();
-    } else if (externalFactory == null) {
+      transactionFactory = externalFactory;
+    } else if (transactionFactory != externalFactory) {
       throw new QueryException("Attempt to use external transaction control in internally managed session");
     }
   }
@@ -702,13 +725,13 @@
 
   public XAResource getXAResource() throws QueryException {
     assertExternallyManagedXA();
-    return externalFactory.getXAResource(this, true);
+    return externalFactory.getXAResource(true);
   }
 
 
   public XAResource getReadOnlyXAResource() throws QueryException {
     assertExternallyManagedXA();
-    return externalFactory.getXAResource(this, false);
+    return externalFactory.getXAResource(false);
   }
 
   public void setIdleTimeout(long millis) {

Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java	2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java	2008-07-07 12:53:59 UTC (rev 1057)
@@ -45,6 +45,7 @@
 import org.mulgara.resolver.spi.*;
 import org.mulgara.server.*;
 import org.mulgara.store.statement.StatementStore;
+import org.mulgara.transaction.TransactionManagerFactory;
 
 /**
  * A JRDF database session.
@@ -115,6 +116,7 @@
    * @throws IllegalArgumentException if any argument is <code>null</code>
    */
   LocalJRDFDatabaseSession(MulgaraTransactionManager transactionManager, 
+      TransactionManagerFactory transactionManagerFactory,
       List securityAdapterList, List symbolicTransformationList,
       ResolverSessionFactory resolverSessionFactory,
       SystemResolverFactory systemResolverFactory,
@@ -123,8 +125,8 @@
       DatabaseMetadata metadata, ContentHandlerManager contentHandlers,
       Set cachedResolverFactorySet, URI temporaryModelTypeURI)
       throws ResolverFactoryException {
-    super(transactionManager, securityAdapterList, symbolicTransformationList,
-        resolverSessionFactory,
+    super(transactionManager, transactionManagerFactory, securityAdapterList,
+        symbolicTransformationList, resolverSessionFactory,
         systemResolverFactory, temporaryResolverFactory, resolverFactoryList,
         externalResolverFactoryMap, internalResolverFactoryMap, metadata,
         contentHandlers, cachedResolverFactorySet, temporaryModelTypeURI);

Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java	2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java	2008-07-07 12:53:59 UTC (rev 1057)
@@ -21,6 +21,7 @@
 // Java2 packages
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import javax.transaction.xa.XAResource;
@@ -31,7 +32,6 @@
 // Local packages
 import org.mulgara.query.MulgaraTransactionException;
 import org.mulgara.query.QueryException;
-import org.mulgara.util.Assoc1toNMap;
 
 /**
  * Manages external transactions.
@@ -48,41 +48,40 @@
  */
 
 public class MulgaraExternalTransactionFactory extends MulgaraTransactionFactory {
-  private Map<DatabaseSession, MulgaraExternalTransaction> associatedTransaction;
-  private Assoc1toNMap<DatabaseSession, MulgaraExternalTransaction> sessionXAMap;
+  private final Set<MulgaraExternalTransaction> transactions;
 
-  private Map<DatabaseSession, MulgaraXAResourceContext> xaResources;
+  private final MulgaraXAResourceContext xaResource;
 
-  public MulgaraExternalTransactionFactory(MulgaraTransactionManager manager) {
-    super(manager);
+  private MulgaraExternalTransaction associatedTransaction;
 
-    this.associatedTransaction = new HashMap<DatabaseSession, MulgaraExternalTransaction>();
-    this.sessionXAMap = new Assoc1toNMap<DatabaseSession, MulgaraExternalTransaction>();
-    this.xaResources = new HashMap<DatabaseSession, MulgaraXAResourceContext>();
+  public MulgaraExternalTransactionFactory(DatabaseSession session, MulgaraTransactionManager manager) {
+    super(session, manager);
+
+    this.associatedTransaction = null;
+    this.transactions = new HashSet<MulgaraExternalTransaction>();
+    this.xaResource = new MulgaraXAResourceContext(this, session);
   }
 
-  public MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
-      throws MulgaraTransactionException {
+  public MulgaraTransaction getTransaction(boolean write) throws MulgaraTransactionException {
     acquireMutex();
     try {
-      MulgaraExternalTransaction xa = associatedTransaction.get(session);
-      if (xa == null) {
+      if (associatedTransaction == null) {
         throw new MulgaraTransactionException("No externally mediated transaction associated with session");
-      } else if (write && xa != writeTransaction) {
+      } else if (write && associatedTransaction != writeTransaction) {
         throw new MulgaraTransactionException("RO-transaction associated with session when requesting write operation");
       }
 
-      return xa;
+      return associatedTransaction;
     } finally {
       releaseMutex();
     }
   }
 
-  protected MulgaraExternalTransaction createTransaction(final DatabaseSession session, Xid xid, boolean write)
+  protected MulgaraExternalTransaction createTransaction(Xid xid, boolean write)
       throws MulgaraTransactionException {
     acquireMutex();
     try {
-      if (associatedTransaction.get(session) != null) {
+      if (associatedTransaction != null) {
         throw new MulgaraTransactionException(
             "Attempt to initiate transaction with existing transaction active with session");
       }
@@ -91,18 +90,18 @@
       }
 
       if (write) {
-          // see comment in MulgaraInternalTransactionFactory regarding releasing the lock here
-          runWithoutMutex(new TransactionOperation() {
-            public void execute() throws MulgaraTransactionException {
-              manager.obtainWriteLock(session);
-            }
-          });
+        // see comment in MulgaraInternalTransactionFactory regarding releasing the lock here
+        runWithoutMutex(new TransactionOperation() {
+          public void execute() throws MulgaraTransactionException {
+            manager.obtainWriteLock(session);
+          }
+        });
         try {
           MulgaraExternalTransaction xa = new MulgaraExternalTransaction(this, xid, session.newOperationContext(true));
           writeTransaction = xa;
-          associatedTransaction.put(session, xa);
-          sessionXAMap.put(session, xa);
-          transactionCreated(xa, session);
+          associatedTransaction = xa;
+          transactions.add(xa);
+          transactionCreated(xa);
 
           return xa;
         } catch (Throwable th) {
@@ -112,9 +111,9 @@
       } else {
         try {
           MulgaraExternalTransaction xa = new MulgaraExternalTransaction(this, xid, session.newOperationContext(false));
-          associatedTransaction.put(session, xa);
-          sessionXAMap.put(session, xa);
-          transactionCreated(xa, session);
+          associatedTransaction = xa;
+          transactions.add(xa);
+          transactionCreated(xa);
 
           return xa;
         } catch (QueryException eq) {
@@ -126,83 +125,57 @@
     }
   }
 
-  public Set<MulgaraExternalTransaction> getTransactionsForSession(DatabaseSession session) {
-    acquireMutex();
-    try {
-      Set<MulgaraExternalTransaction> xas = sessionXAMap.getN(session);
-      return xas != null ? xas : Collections.<MulgaraExternalTransaction>emptySet();
-    } finally {
-      releaseMutex();
-    }
+  protected Set<MulgaraExternalTransaction> getTransactions() {
+    return transactions;
   }
 
-  public XAResource getXAResource(DatabaseSession session, boolean writing) {
+  public XAResource getXAResource(boolean writing) {
     acquireMutex();
     try {
-      MulgaraXAResourceContext xarc = xaResources.get(session);
-      if (xarc == null) {
-        xarc = new MulgaraXAResourceContext(this, session);
-        xaResources.put(session, xarc);
-      }
-
-      return xarc.getResource(writing);
+      return xaResource.getResource(writing);
     } finally {
       releaseMutex();
     }
   }
 
-  public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
-    acquireMutex();
-    try {
-      try {
-        super.closingSession(session);
-      } finally {
-        xaResources.remove(session);
-      }
-    } finally {
-      releaseMutex();
-    }
-  }
-
   public void transactionComplete(MulgaraExternalTransaction xa)
       throws MulgaraTransactionException {
     acquireMutex();
-    super.transactionComplete(xa);
-
     try {
+      super.transactionComplete(xa);
+
       if (xa == null) {
         throw new IllegalArgumentException("Null transaction indicated completion");
       }
-      DatabaseSession session = sessionXAMap.get1(xa);
       if (xa == writeTransaction) {
         manager.releaseWriteLock(session);
         writeTransaction = null;
       }
-      sessionXAMap.removeN(xa);
-      if (associatedTransaction.get(session) == xa) {
-        associatedTransaction.remove(session);
+      transactions.remove(xa);
+      if (associatedTransaction == xa) {
+        associatedTransaction = null;
       }
     } finally {
       releaseMutex();
     }
   }
 
-  public boolean hasAssociatedTransaction(DatabaseSession session) {
+  public boolean hasAssociatedTransaction() {
     acquireMutex();
     try {
-      return associatedTransaction.get(session) != null;
+      return associatedTransaction != null;
     } finally {
       releaseMutex();
     }
   }
 
-  public boolean associateTransaction(DatabaseSession session, MulgaraExternalTransaction xa) {
+  public boolean associateTransaction(MulgaraExternalTransaction xa) {
     acquireMutex();
     try {
-      if (associatedTransaction.get(session) != null) {
+      if (associatedTransaction != null) {
         return false;
       } else {
-        associatedTransaction.put(session, xa);
+        associatedTransaction = xa;
         return true;
       }
     } finally {
@@ -210,24 +183,37 @@
     }
   }
 
-  public MulgaraExternalTransaction getAssociatedTransaction(DatabaseSession session) {
+  public MulgaraExternalTransaction getAssociatedTransaction() {
     acquireMutex();
     try {
-      return associatedTransaction.get(session);
+      return associatedTransaction;
     } finally {
       releaseMutex();
     }
   }
 
-  public void disassociateTransaction(DatabaseSession session, MulgaraExternalTransaction xa) 
+  public void disassociateTransaction(MulgaraExternalTransaction xa) 
       throws MulgaraTransactionException {
     acquireMutex();
     try {
-      if (associatedTransaction.get(session) == xa) {
-        associatedTransaction.remove(session);
+      if (associatedTransaction == xa) {
+        associatedTransaction = null;
       }
     } finally {
       releaseMutex();
     }
   }
+
+  public void closingSession() throws MulgaraTransactionException {
+    acquireMutex();
+    try {
+      try {
+        super.closingSession();
+      } finally {
+        transactions.clear();
+      }
+    } finally {
+      releaseMutex();
+    }
+  }
 }

Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java	2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java	2008-07-07 12:53:59 UTC (rev 1057)
@@ -57,37 +57,40 @@
     Logger.getLogger(MulgaraInternalTransactionFactory.class.getName());
 
   /** Set of sessions whose transactions have been rolledback.*/
-  private Set<DatabaseSession> failedSessions;
+  private boolean isFailed;
 
   /** Map of threads to active transactions. */
-  private Map<Thread, MulgaraTransaction> activeTransactions;
+  private final Map<Thread, MulgaraTransaction> activeTransactions;
 
-  /** Map of transactions to associated sessions. */
-  private Map<MulgaraTransaction, DatabaseSession> xaSessionMap;
+  /** Are we in auto-commit mode. */
+  public boolean autoCommit;
 
-  /** Per session info. */
-  private Map<DatabaseSession, SessionInfo> sessionInfoMap;
+  /** All uncompleted transactions (may be more than 1 because of unclosed answers) */
+  public final Set<MulgaraTransaction> transactions;
 
+  /** Currently associated explicit transaction */
+  public MulgaraInternalTransaction explicitXA;
+
   private final TransactionManager transactionManager;
 
-  public MulgaraInternalTransactionFactory(MulgaraTransactionManager manager, TransactionManagerFactory transactionManagerFactory) {
-    super(manager);
+  public MulgaraInternalTransactionFactory(DatabaseSession session, MulgaraTransactionManager manager,
+                                           TransactionManagerFactory transactionManagerFactory) {
+    super(session, manager);
 
-    this.failedSessions = new HashSet<DatabaseSession>();
+    this.isFailed = false;
     this.activeTransactions = new HashMap<Thread, MulgaraTransaction>();
-    this.xaSessionMap = new HashMap<MulgaraTransaction, DatabaseSession>();
-    this.sessionInfoMap = new HashMap<DatabaseSession, SessionInfo>();
+    this.autoCommit = true;
+    this.transactions = new HashSet<MulgaraTransaction>();
+    this.explicitXA = null;
 
     this.transactionManager = transactionManagerFactory.newTransactionManager();
   }
 
-  public MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
-      throws MulgaraTransactionException {
+  public MulgaraTransaction getTransaction(boolean write) throws MulgaraTransactionException {
     acquireMutex();
     try {
-      SessionInfo sessInfo = getOrCreateSessionInfo(session);
-      if (sessInfo.explicitXA != null) {
-        return sessInfo.explicitXA;
+      if (explicitXA != null) {
+        return explicitXA;
       }
 
       try {
@@ -106,7 +109,7 @@
           try {
             assert writeTransaction == null;
             writeTransaction = transaction = 
-                new MulgaraInternalTransaction(this, session.newOperationContext(true));
+              new MulgaraInternalTransaction(this, session.newOperationContext(true));
           } catch (Throwable th) {
             manager.releaseWriteLock(session);
             throw new MulgaraTransactionException("Error creating write transaction", th);
@@ -115,9 +118,8 @@
           transaction = new MulgaraInternalTransaction(this, session.newOperationContext(false));
         }
 
-        xaSessionMap.put(transaction, session);
-        sessInfo.transactions.add(transaction);
-        transactionCreated(transaction, session);
+        transactions.add(transaction);
+        transactionCreated(transaction);
 
         return transaction;
       } catch (MulgaraTransactionException em) {
@@ -130,26 +132,15 @@
     }
   }
 
-  public Set<MulgaraTransaction> getTransactionsForSession(DatabaseSession session) {
-    acquireMutex();
-    try {
-      SessionInfo sessInfo = sessionInfoMap.get(session);
-      return sessInfo == null ? Collections.<MulgaraTransaction>emptySet() : sessInfo.transactions;
-    } finally {
-      releaseMutex();
-    }
+  public Set<MulgaraTransaction> getTransactions() {
+    return transactions;
   }
 
-  public MulgaraTransaction newMulgaraTransaction(DatabaseOperationContext context)
-      throws MulgaraTransactionException {
-    return new MulgaraInternalTransaction(this, context);
-  }
 
-
-  public void commit(DatabaseSession session) throws MulgaraTransactionException {
+  public void commit() throws MulgaraTransactionException {
     acquireMutex();
     try {
-      if (failedSessions.contains(session)) {
+      if (isFailed) {
         throw new MulgaraTransactionException("Attempting to commit failed session");
       } else if (!manager.isHoldingWriteLock(session)) {
         throw new MulgaraTransactionException(
@@ -158,8 +149,8 @@
 
       manager.reserveWriteLock(session);
       try {
-        setAutoCommit(session, true);
-        setAutoCommit(session, false);
+        setAutoCommit(true);
+        setAutoCommit(false);
       } finally {
         manager.releaseReserve(session);
       }
@@ -174,7 +165,7 @@
    * 
    * This needs to be distinguished from an implicit rollback triggered by failure.
    */
-  public void rollback(DatabaseSession session) throws MulgaraTransactionException {
+  public void rollback() throws MulgaraTransactionException {
     acquireMutex();
     try {
       if (manager.isHoldingWriteLock(session)) {
@@ -182,10 +173,10 @@
         try {
           try {
             writeTransaction.execute(new TransactionOperation() {
-                public void execute() throws MulgaraTransactionException {
-                  writeTransaction.dereference();
-                  ((MulgaraInternalTransaction)writeTransaction).explicitRollback();
-                }
+              public void execute() throws MulgaraTransactionException {
+                writeTransaction.dereference();
+                ((MulgaraInternalTransaction)writeTransaction).explicitRollback();
+              }
             });
             // FIXME: Should be checking status here, not writelock.
             if (manager.isHoldingWriteLock(session)) {
@@ -194,16 +185,16 @@
                   new MulgaraTransactionException("Rollback failed to terminate write transaction"));
             }
           } finally {
-            sessionInfoMap.get(session).explicitXA = null;
-            setAutoCommit(session, false);
+            explicitXA = null;
+            setAutoCommit(false);
           }
         } finally {
           manager.releaseReserve(session);
         }
-      } else if (failedSessions.contains(session)) {
-        sessionInfoMap.get(session).explicitXA = null;
-        failedSessions.remove(session);
-        setAutoCommit(session, false);
+      } else if (isFailed) {
+        explicitXA = null;
+        isFailed = false;
+        setAutoCommit(false);
       } else {
         throw new MulgaraTransactionException(
             "Attempt to rollback while not in the current writing transaction");
@@ -213,21 +204,18 @@
     }
   }
 
-  public void setAutoCommit(DatabaseSession session, boolean autoCommit)
-      throws MulgaraTransactionException {
+  public void setAutoCommit(boolean autoCommit) throws MulgaraTransactionException {
     acquireMutex();
     try {
-      if (manager.isHoldingWriteLock(session) && failedSessions.contains(session)) {
+      if (manager.isHoldingWriteLock(session) && isFailed) {
         writeTransaction.abortTransaction("Session failed and still holding writeLock",
-            new MulgaraTransactionException("Failed Session in setAutoCommit"));
+                              new MulgaraTransactionException("Failed Session in setAutoCommit"));
       }
 
-      SessionInfo sessInfo = getOrCreateSessionInfo(session);
-
-      if (manager.isHoldingWriteLock(session) || failedSessions.contains(session)) {
+      if (manager.isHoldingWriteLock(session) || isFailed) {
         if (autoCommit) {
-          sessInfo.autoCommit = true;
-          sessInfo.explicitXA = null;
+          this.autoCommit = true;
+          this.explicitXA = null;
 
           // AutoCommit off -> on === branch on current state of transaction.
           if (manager.isHoldingWriteLock(session)) {
@@ -253,9 +241,9 @@
                 manager.releaseWriteLock(session);
               }
             }
-          } else if (failedSessions.contains(session)) {
+          } else if (isFailed) {
             // Within failed transaction - cleanup.
-            failedSessions.remove(session);
+            isFailed = false;
           }
         } else {
           if (!manager.isHoldingWriteLock(session)) {
@@ -268,16 +256,16 @@
           }
         }
       } else {
-        sessInfo.explicitXA = null;
+        explicitXA = null;
         if (autoCommit) {
           // AutoCommit on -> on === no-op.  Log info.
           logger.info("Attempting to set autocommit true without setting it false");
         } else {
           // AutoCommit on -> off == Start new transaction.
-          getTransaction(session, true); // Set's writeTransaction.
+          getTransaction(true); // Set's writeTransaction.
           writeTransaction.reference();
-          sessInfo.explicitXA = writeTransaction;
-          sessInfo.autoCommit = false;
+          explicitXA = (MulgaraInternalTransaction) writeTransaction;
+          this.autoCommit = false;
         }
       }
     } finally {
@@ -301,7 +289,7 @@
           throw new MulgaraTransactionException("Attempt to start transaction twice");
         }
 
-        setTransactionTimeout((int) (xaSessionMap.get(transaction).getTransactionTimeout() / 1000));
+        setTransactionTimeout((int) (session.getTransactionTimeout() / 1000));
         transactionManager.begin();
         Transaction jtaTrans = transactionManager.getTransaction();
 
@@ -326,7 +314,7 @@
       } else if (activeTransactions.containsValue(transaction)) {
         throw new MulgaraTransactionException("Attempt to resume active transaction");
       }
-      
+
       try {
         transactionManager.resume(jtaXA);
         activeTransactions.put(Thread.currentThread(), transaction);
@@ -348,8 +336,7 @@
               "Attempt to suspend transaction from outside thread");
         }
 
-        SessionInfo sessInfo = sessionInfoMap.get(xaSessionMap.get(transaction));
-        if (sessInfo.autoCommit && transaction == writeTransaction) {
+        if (autoCommit && transaction == writeTransaction) {
           logger.error("Attempt to suspend write transaction without setting AutoCommit Off");
           throw new MulgaraTransactionException(
               "Attempt to suspend write transaction without setting AutoCommit Off");
@@ -373,16 +360,13 @@
     }
   }
 
-  public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
+  public void closingSession() throws MulgaraTransactionException {
     acquireMutex();
     try {
       try {
-        super.closingSession(session);
+        super.closingSession();
       } finally {
-        SessionInfo sessInfo = sessionInfoMap.remove(session);
-        if (sessInfo != null) {
-          xaSessionMap.keySet().removeAll(sessInfo.transactions);
-        }
+        transactions.clear();
       }
     } finally {
       releaseMutex();
@@ -391,14 +375,11 @@
 
   public void transactionComplete(MulgaraTransaction transaction) throws MulgaraTransactionException {
     acquireMutex();
-    super.transactionComplete(transaction);
-
     try {
+      super.transactionComplete(transaction);
+
       logger.debug("Transaction Complete");
-      DatabaseSession session = xaSessionMap.get(transaction);
-      if (session == null) {
-        throw new MulgaraTransactionException("No associated session found for transaction");
-      }
+
       if (transaction == writeTransaction) {
         if (manager.isHoldingWriteLock(session)) {
           manager.releaseWriteLock(session);
@@ -406,8 +387,7 @@
         }
       }
 
-      xaSessionMap.remove(transaction);
-      sessionInfoMap.get(session).transactions.remove(transaction);
+      transactions.remove(transaction);
       activeTransactions.remove(Thread.currentThread());
     } finally {
       releaseMutex();
@@ -419,9 +399,8 @@
     try {
       try {
         // Make sure this cleans up the transaction metadata - this transaction is DEAD!
-        SessionInfo sessInfo = sessionInfoMap.get(xaSessionMap.get(transaction));
-        if (!sessInfo.autoCommit && transaction == writeTransaction) {
-          failedSessions.add(xaSessionMap.get(transaction));
+        if (!autoCommit && transaction == writeTransaction) {
+          isFailed = true;
         }
         transactionComplete(transaction);
       } catch (Throwable th) {
@@ -440,21 +419,4 @@
       logger.warn("Unable to set transaction timeout: " + transactionTimeout, es);
     }
   }
-
-  private SessionInfo getOrCreateSessionInfo(DatabaseSession session) {
-    SessionInfo info = sessionInfoMap.get(session);
-    if (info == null)
-      sessionInfoMap.put(session, info = new SessionInfo());
-    return info;
-  }
-
-  private static class SessionInfo {
-    public boolean autoCommit = true;
-
-    /** All uncompleted transactions (may be more than 1 because of unclosed answers) */
-    public Set<MulgaraTransaction> transactions = new HashSet<MulgaraTransaction>();
-
-    /** Currently associated explicit transaction */
-    public MulgaraTransaction explicitXA;
-  }
 }

Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java	2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java	2008-07-07 12:53:59 UTC (rev 1057)
@@ -66,6 +66,7 @@
   protected final IdleReaper idleReaperTask;
   protected long idleTimeout;
   protected ExtXAReaper extXAReaperTask;
+  protected final DatabaseSession session;
 
   /**
    * Contains a reference the the current writing transaction IFF it is managed
@@ -76,7 +77,8 @@
 
   private ReentrantLock mutex;
 
-  protected MulgaraTransactionFactory(MulgaraTransactionManager manager) {
+  protected MulgaraTransactionFactory(DatabaseSession session, MulgaraTransactionManager manager) {
+    this.session = session;
     this.manager = manager;
     this.mutex = new ReentrantLock();
     this.writeTransaction = null;
@@ -86,7 +88,7 @@
   }
 
 
-  protected void transactionCreated(MulgaraTransaction transaction, DatabaseSession session) {
+  protected void transactionCreated(MulgaraTransaction transaction) {
     if (transaction != writeTransaction)
       return;
 
@@ -110,17 +112,17 @@
    * otherwise creates a new transaction context and associates it with the
    * session.
    */
-  public abstract MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
+  public abstract MulgaraTransaction getTransaction(boolean write)
       throws MulgaraTransactionException;
-  
-  protected abstract Set<? extends MulgaraTransaction> getTransactionsForSession(DatabaseSession session);
 
+  protected abstract Set<? extends MulgaraTransaction> getTransactions();
+
   /**
    * Rollback, or abort all transactions associated with a DatabaseSession.
    *
    * Will only abort the transaction if the rollback attempt fails.
    */
-  public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
+  public void closingSession() throws MulgaraTransactionException {
     acquireMutex();
     logger.debug("Cleaning up any stale transactions on session close");
     try {
@@ -156,7 +158,7 @@
           logger.debug("Session does not hold write-lock");
         }
 
-        for (MulgaraTransaction transaction : getTransactionsForSession(session)) {
+        for (MulgaraTransaction transaction : getTransactions()) {
           try {
             // This is final so we can create the closure.
             final MulgaraTransaction xa = transaction;

Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2008-07-07 12:53:59 UTC (rev 1057)
@@ -30,17 +30,14 @@
 
 // Local packages
 import org.mulgara.query.MulgaraTransactionException;
-import org.mulgara.transaction.TransactionManagerFactory;
 
 /**
  * Manages the Write-Lock.
  *
  * Manages tracking the ownership of the write-lock.
- * Provides new/existing TransactionContext's to DatabaseSession on request.
- *    Note: Returns new context unless Session is currently in a User Demarcated Transaction.
  * Provides a facility to trigger a heuristic rollback of any transactions still
  *   valid on session close.
- * Maintains the write-queue and any timeout algorithm desired.
+ * Maintains the write-queue
  *
  * @created 2006-10-06
  *
@@ -74,29 +71,14 @@
   private final ReentrantLock mutex;
   private final Condition writeLockCondition;
 
-  private final MulgaraInternalTransactionFactory internalFactory;
-  private final MulgaraExternalTransactionFactory externalFactory;
-
-  public MulgaraTransactionManager(TransactionManagerFactory transactionManagerFactory) {
+  public MulgaraTransactionManager() {
     this.sessionHoldingWriteLock = null;
     this.sessionReservingWriteLock = null;
     this.mutex = new ReentrantLock();
     this.writeLockCondition = this.mutex.newCondition();
-
-    this.internalFactory = new MulgaraInternalTransactionFactory(this, transactionManagerFactory);
-    this.externalFactory = new MulgaraExternalTransactionFactory(this);
   }
 
 
-  MulgaraInternalTransactionFactory getInternalFactory() {
-    return internalFactory;
-  }
-
-  MulgaraExternalTransactionFactory getExternalFactory() {
-    return externalFactory;
-  }
-
-
   /** 
    * Obtains the write lock.
    */
@@ -224,28 +206,12 @@
   }
 
   public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
-    // Calls to final fields do not require mutex.  As both of these calls
-    // potentially call back into the manager, calling these while holding the
-    // lock can invalidate lock-ordering and result in a deadlock.
-    Throwable error = null;
-    try {
-      internalFactory.closingSession(session);
-    } catch (Throwable th) {
-      logger.error("Error signalling session-close to internal xa-factory", th);
-      error = (error == null) ? th : error;
-    }
-
-    try {
-      externalFactory.closingSession(session);
-    } catch (Throwable th) {
-      logger.error("Error signalling session-close to external xa-factory", th);
-      error = (error == null) ? th : error;
-    }
-
     // This code should not be required, but is there to ensure the manager is
     // reset regardless of errors in the factories.
     acquireMutex();
     try {
+      Throwable error = null;
+
       if (writeLockReserved(session)) {
         try {
           releaseReserve(session);

Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java	2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java	2008-07-07 12:53:59 UTC (rev 1057)
@@ -208,7 +208,7 @@
 
         try {
           // If XA is currently associated with session, disassociate it.
-          factory.disassociateTransaction(session, xa);
+          factory.disassociateTransaction(xa);
         } catch (MulgaraTransactionException em) {
           logger.error("Error disassociating transaction from session", em);
           throw new XAException(XAException.XAER_PROTO);
@@ -366,12 +366,12 @@
           case TMNOFLAGS:
             if (xa2xid.containsN(xid)) {
               throw new XAException(XAException.XAER_DUPID);
-            } else if (factory.hasAssociatedTransaction(session)) {
+            } else if (factory.hasAssociatedTransaction()) {
               throw new XAException(XAException.XA_RBDEADLOCK);
             } else {
               // FIXME: Need to consider read-only transactions here.
               try {
-                MulgaraExternalTransaction xa = factory.createTransaction(session, xid, writing);
+                MulgaraExternalTransaction xa = factory.createTransaction(xid, writing);
                 xa2xid.put(xa, xid);
               } catch (MulgaraTransactionException em) {
                 logger.error("Failed to create transaction", em);
@@ -380,9 +380,9 @@
             }
             break;
           case TMJOIN:
-            if (!factory.hasAssociatedTransaction(session)) {
+            if (!factory.hasAssociatedTransaction()) {
               throw new XAException(XAException.XAER_NOTA);
-            } else if (!factory.getAssociatedTransaction(session).getXid().equals(xid)) {
+            } else if (!factory.getAssociatedTransaction().getXid().equals(xid)) {
               throw new XAException(XAException.XAER_OUTSIDE);
             }
             break;
@@ -393,7 +393,7 @@
             } else if (xa.isRollbacked()) {
               throw new XAException(XAException.XA_RBROLLBACK);
             } else {
-              if (!factory.associateTransaction(session, xa)) {
+              if (!factory.associateTransaction(xa)) {
                 // session already associated with a transaction.
                 throw new XAException(XAException.XAER_PROTO);
               }
@@ -416,7 +416,7 @@
      */
     private DatabaseSession getSession() { return session; }
   }
-  
+
   /**
    * Used to replace the built in monitor to allow it to be properly released
    * during potentially blocking operations.  All potentially blocking




More information about the Mulgara-svn mailing list