[Mulgara-svn] r562 - branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver

andrae at mulgara.org andrae at mulgara.org
Fri Nov 16 06:14:02 UTC 2007


Author: andrae
Date: 2007-11-16 00:14:01 -0600 (Fri, 16 Nov 2007)
New Revision: 562

Modified:
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java
Log:
Moved all the transaction initiation code into the concrete classes as external
and internal transactions have different ideas as to when to create a
transaction and what it means for a transaction to be 'the current' transaction.

Specifically the external code has no concept of an implicit transaction.  All
transactions are started via the XAResource.  The internal code has no concept
of suspending a transactions association with a session - it tracks only the
current transaction, and transactions with outstanding answers.

Note: To make life easier for the clients we are not requiring transactions to
be reassociated with the session prior to the use of any Answers obtained from
them - however we will require that the transaction exist and not be completed
in someway.



Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java	2007-11-16 02:59:00 UTC (rev 561)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java	2007-11-16 06:14:01 UTC (rev 562)
@@ -45,29 +45,119 @@
  */
 
 public class MulgaraExternalTransactionFactory implements MulgaraTransactionFactory {
-  private Map<DatabaseSession, MulgaraExternalTransaction> activeTransaction;
+  private Map<DatabaseSession, MulgaraExternalTransaction> associatedTransaction;
   private Assoc1toNMap<DatabaseSession, MulgaraExternalTransaction> sessionXAMap;
 
+  private Map<DatabaseSession, MulgaraXAResource> xaResources;
 
-  public MulgaraExternalTransactionFactory() {
-    super();
+  private MulgaraExternalTransaction writeTransaction;
+
+  public MulgaraExternalTransactionFactory(MulgaraTransactionManager manager) {
+    super(manager);
+
+    this.associatedTransaction = new HashMap<DatabaseSession, MulgaraExternalTransaction>();
+    this.sessionXAMap = new Assoc1toNMap<DatabaseSession, MulgaraExternalTransaction>();
+    this.xaResources = new HashMap<DatabaseSession, MulgaraXAResource>();
+    this.writeTransaction = null;
   }
 
-  protected MulgaraTransaction createTransaction(final DatabaseSession session, boolean write)
+  public MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
       throws MulgaraTransactionException {
-    return new MulgaraExternalTransaction(this, write);
+    acquireMutex();
+    try {
+      MulgaraExternalTransaction xa = associatedTransaction.get(session);
+      if (xa == null) {
+        throw new MulgaraTransactionException("No externally mediated transaction associated with session");
+      } else if (write && !xa.isWriteTransaction()) {
+        throw new MulgaraTransactionException("RO-transaction associated with session when requesting write operation");
+      }
+
+      return xa;
+    } finally {
+      releaseMutex();
+    }
   }
 
-  /**
-   * Rollback, or abort all transactions associated with a DatabaseSession.
-   *
-   * Will only abort the transaction if the rollback attempt fails.
-   */
-  public void rollbackCurrentTransactions(DatabaseSession session)
+  protected MulgaraTransaction createTransaction(final DatabaseSession session, boolean write)
       throws MulgaraTransactionException {
+    acquireMutex();
+    try {
+      if (associatedTransaction.get(session) != null) {
+        throw new MulgaraTransactionException(
+            "Attempt to initiate transaction with existing transaction active with session");
+      }
+      if (write && manager.isHoldingWriteLock(session)) {
+        throw new MulgaraTransactionException("Attempt to initiate two write transactions from the same session");
+      }
+
+      if (write) {
+          runWithoutMutex(new TransactionOperation() {
+            public void execute() throws MulgaraTransactionException {
+              manager.obtainWriteLock(session);
+            }
+          });
+        try {
+          MulgaraExternalTransaction xa = new MulgaraExternalTransaction(this, session.newOperationContext(true));
+          associatedTransaction.put(session, xa);
+          sessionXAMap.put(session, xa);
+        } catch (Throwable th) {
+          manager.releaseWriteLock(session);
+          throw new MulgaraTransactionException("Error initiating write transaction", th);
+        }
+      } else {
+        MulgaraExternalTransaction xa = new MulgaraExternalTransaction(this, session.newOperationContext(false));
+        associatedTransaction.put(session, xa);
+      }
+    } finally {
+      releaseMutex();
+    }
   }
 
+
   public XAResource getXAResource(DatabaseSession session) {
-    return new MulgaraXAResource(this, session);
+    acquireMutex();
+    try {
+      MulgaraXAResource xar = xaResources.get(session);
+      if (xar == null) {
+        xar = new MulgaraXAResource(this, session);
+        xaResources.put(session, xar);
+      }
+
+      return xar;
+    } finally {
+      releaseMutex();
+    }
   }
+
+  public void closingSession(DatabaseSession session) {
+    acquireMutex();
+    try {
+      MulgaraXAResource xar = xaResources.remove(session);
+      if (xar != null) {
+        xar.close();
+      }
+    } finally {
+      releaseMutex();
+    }
+  }
+
+  public void transactionComplete(MulgaraExternalTransaction xa) {
+    acquireMutex();
+    try {
+      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);
+      }
+    } finally {
+      releaseMutex();
+    }
+  }
 }

Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java	2007-11-16 02:59:00 UTC (rev 561)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java	2007-11-16 06:14:01 UTC (rev 562)
@@ -80,16 +80,50 @@
     this.transactionManager = transactionManagerFactory.newTransactionManager();
   }
 
-  /**
-   * Allows DatabaseSession to initiate/obtain a transaction.
-   * <ul>
-   * <li>If the Session holds the write lock, return the current Write-Transaction.</li>
-   * <li>If the Session does not hold the write lock and requests a read-only transaction,
-   *     create a new ro-transaction object and return it.</li>
-   * <li>If the Session does not hold the write lock and requests a read-write transaction,
-   *     obtain the write-lock, create a new transaction object and return it.</li>
-   * </ul>
-   */
+  public MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
+      throws MulgaraTransactionException {
+    acquireMutex();
+    try {
+      if (write && manager.isHoldingWriteLock(session)) {
+        return writeTransaction;
+      }
+
+      try {
+        MulgaraInternalTransaction transaction;
+        if (write) {
+          runWithoutMutex(new TransactionOperation() {
+            public void execute() throws MulgaraTransactionException {
+              manager.obtainWriteLock(session);
+            }
+          });
+          try {
+            assert writeTransaction == null;
+            writeTransaction = transaction = newMulgaraTransaction(session.newOperationContext(true));
+          } catch (MulgaraTransactionException em) {
+            manager.releaseWriteLock(session);
+            throw em;
+          } catch (Throwable th) {
+            manager.releaseWriteLock(session);
+            throw new MulgaraTransactionException("Error creating write transaction", th);
+          }
+        } else {
+          transaction = newMulgaraTransaction(session.newOperationContext(false));
+        }
+
+        sessionXAMap.put(session, transaction);
+
+        return transaction;
+      } catch (MulgaraTransactionException em) {
+        throw em;
+      } catch (Exception e) {
+        throw new MulgaraTransactionException("Error creating transaction", e);
+      }
+    } finally {
+      releaseMutex();
+    }
+  }
+
+
   public MulgaraTransaction newMulgaraTransaction(DatabaseOperationContext context)
       throws MulgaraTransactionException {
     return new MulgaraInternalTransaction(this, context);

Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java	2007-11-16 02:59:00 UTC (rev 561)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java	2007-11-16 06:14:01 UTC (rev 562)
@@ -73,21 +73,15 @@
    */
   protected MulgaraTransaction writeTransaction;
 
-  protected Map<DatabaseSession, ? extends MulgaraTransaction> activeTransaction;
-
-  protected Assoc1toNMap<DatabaseSession, ? extends MulgaraTransaction> sessionXAMap;
-
   private ReentrantLock mutex;
 
   protected MulgaraTransactionFactory(MulgaraTransactionManager manager) {
     this.manager = manager;
     this.mutex = new ReentrantLock();
     this.writeTransaction = null;
-
-    this.activeTransaction = new Map<DatabaseSession, ? extends MulgaraTransaction>();
-    this.sessionXAMap = new Assoc1toNMap<DatabaseSession, ? extends MulgaraTransaction>();
   }
 
+
   /**
    * Obtain a transaction context associated with a DatabaseSession.
    *
@@ -98,57 +92,17 @@
    * otherwise creates a new transaction context and associates it with the
    * session.
    */
-  public MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
-      throws MulgaraTransactionException {
-    acquireMutex();
-    try {
-      if (write && manager.isHoldingWriteLock(session)) {
-        return writeTransaction;
-      }
+  public abstract MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
+      throws MulgaraTransactionException;
+  
+  protected abstract getTransactionsForSession(DatabaseSession session);
 
-      try {
-        MulgaraInternalTransaction transaction;
-        if (write) {
-          runWithoutMutex(new TransactionOperation() {
-            public void execute() throws MulgaraTransactionException {
-              manager.obtainWriteLock(session);
-            }
-          });
-          try {
-            assert writeTransaction == null;
-            writeTransaction = transaction = newMulgaraTransaction(session.newOperationContext(true));
-          } catch (MulgaraTransactionException em) {
-            manager.releaseWriteLock(session);
-            throw em;
-          } catch (Throwable th) {
-            manager.releaseWriteLock(session);
-            throw new MulgaraTransactionException("Error creating write transaction", th);
-          }
-        } else {
-          transaction = newMulgaraTransaction(session.newOperationContext(false));
-        }
-
-        sessionXAMap.put(session, transaction);
-
-        return transaction;
-      } catch (MulgaraTransactionException em) {
-        throw em;
-      } catch (Exception e) {
-        throw new MulgaraTransactionException("Error creating transaction", e);
-      }
-    } finally {
-      releaseMutex();
-    }
-  }
-
-  protected abstract MulgaraTransaction newMulgaraTransaction(DatabaseOperationContext context);
-
   /**
    * Rollback, or abort all transactions associated with a DatabaseSession.
    *
    * Will only abort the transaction if the rollback attempt fails.
    */
-  public void rollbackCurrentTransactions(DatabaseSession session) throws MulgaraTransactionException {
+  public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
     acquireMutex();
     try {
       try {
@@ -202,7 +156,7 @@
   /**
    * Abort as many of the transactions as we can.
    */
-  private void abortTransactions(Set<MulgaraTransaction> requiresAbort) {
+  protected void abortTransactions(Set<MulgaraTransaction> requiresAbort) {
     try {
       if (!requiresAbort.empty()) {
         // At this point the originating exception has been thrown in the caller




More information about the Mulgara-svn mailing list