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

andrae at mulgara.org andrae at mulgara.org
Mon Feb 11 11:54:20 UTC 2008


Author: andrae
Date: 2008-02-11 03:54:20 -0800 (Mon, 11 Feb 2008)
New Revision: 639

Modified:
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.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
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
Log:
Fixes a bug where an open transaction may not be properly cleaned up on session
close.  The sequence of operations required to reproduce the bug is:

s1.setAutoCommit(false);
s1.commit();
s1.close();
s2.setAutoCommit(false);

This was due to sessionClose() being called on both the Manager and the Factory.
The call to Manager reset state that was required to correctly identify what
needed to be reset in the Factory.

Fixed by removing the extra call to sessionClose() on the Factory, and replacing
this with a call from the manager to the factory within MTManager::sessionClose()
before any state is reset.



Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2008-02-11 07:38:03 UTC (rev 638)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2008-02-11 11:54:20 UTC (rev 639)
@@ -554,18 +554,10 @@
     logger.info("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);
-    } finally {
-      try {
-        if (transactionFactory != null) {
-          transactionFactory.closingSession(this);
-        }
-      } catch (MulgaraTransactionException em) {
-        logger.error("Error closing session", em);
-        throw new QueryException("Error closing session. Forced close required", em);
-      }
     }
   }
 

Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java	2008-02-11 07:38:03 UTC (rev 638)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java	2008-02-11 11:54:20 UTC (rev 639)
@@ -119,6 +119,7 @@
     suite.addTest(new ExternalTransactionUnitTest("testExternalInternalConcurrentTxn"));
     suite.addTest(new ExternalTransactionUnitTest("testInternalExternalConcurrentTxnRollback"));
     suite.addTest(new ExternalTransactionUnitTest("testExternalInternalConcurrentTxnRollback"));
+    suite.addTest(new ExternalTransactionUnitTest("testInternalSerialMultipleSessions"));
 
     return suite;
   }
@@ -1945,6 +1946,36 @@
   }
 
 
+  /**
+   * Tests cleaning up a transaction on close.  This test added in the process
+   * of fixing a bug reported by Ronald on the JTA-beta.
+   */
+  public void testInternalSerialMultipleSessions() throws URISyntaxException
+  {
+    logger.info("testInternalSerialMultipleSessions");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session1 = database.newSession();
+      Session session2 = database.newSession();
+      try {
+        session1.createModel(model4URI, null);
+
+        session1.setAutoCommit(false);
+        session1.setModel(model4URI, new ModelResource(fileURI));
+
+        session1.commit();
+        session1.close();
+
+        session2.setAutoCommit(false);
+      } finally {
+        session2.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
   //
   // Internal methods
   //

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	2008-02-11 07:38:03 UTC (rev 638)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java	2008-02-11 11:54:20 UTC (rev 639)
@@ -358,6 +358,7 @@
   public void transactionComplete(MulgaraTransaction transaction) throws MulgaraTransactionException {
     acquireMutex();
     try {
+      logger.debug("Transaction Complete");
       DatabaseSession session = sessionXAMap.get1(transaction);
       if (session == null) {
         throw new MulgaraTransactionException("No associated session found for transaction");

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	2008-02-11 07:38:03 UTC (rev 638)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java	2008-02-11 11:54:20 UTC (rev 639)
@@ -106,30 +106,37 @@
    */
   public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
     acquireMutex();
+    logger.debug("Cleaning up any stale transactions on session close");
     try {
       Map<MulgaraTransaction, Throwable> requiresAbort = new HashMap<MulgaraTransaction, Throwable>();
       try {
         Throwable error = null;
 
         if (manager.isHoldingWriteLock(session)) {
+          logger.debug("Session holds write-lock");
           try {
             if (writeTransaction != null) {
-              logger.warn("Terminating session while holding writelock:" + session + ": " + writeTransaction);
-              writeTransaction.execute(new TransactionOperation() {
-                  public void execute() throws MulgaraTransactionException {
-                    writeTransaction.heuristicRollback("Session closed while holding write lock");
-                  }
-              });
+              try {
+                logger.warn("Terminating session while holding writelock:" + session + ": " + writeTransaction);
+                writeTransaction.execute(new TransactionOperation() {
+                    public void execute() throws MulgaraTransactionException {
+                      writeTransaction.heuristicRollback("Session closed while holding write lock");
+                    }
+                });
+              } catch (Throwable th) {
+                if (writeTransaction != null) {
+                  requiresAbort.put(writeTransaction, th);
+                  error = th;
+                }
+              } finally {
+                writeTransaction = null;
+              }
             }
-          } catch (Throwable th) {
-            if (writeTransaction != null) {
-              requiresAbort.put(writeTransaction, th);
-              error = th;
-            }
           } finally {
             manager.releaseWriteLock(session);
-            writeTransaction = null;
           }
+        } else {
+          logger.debug("Session does not hold write-lock");
         }
 
         for (MulgaraTransaction transaction : getTransactionsForSession(session)) {

Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2008-02-11 07:38:03 UTC (rev 638)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2008-02-11 11:54:20 UTC (rev 639)
@@ -231,29 +231,39 @@
     acquireMutex();
     try {
       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;
+      }
+
       if (writeLockReserved(session)) {
         try {
           releaseReserve(session);
         } catch (Throwable th) {
           logger.error("Error releasing reserve on force-close", th);
-          error = th;
+          error = (error == null) ? th : error;
         }
       }
+
       if (isHoldingWriteLock(session)) {
         try {
           releaseWriteLock(session);
         } catch (Throwable th) {
           logger.error("Error releasing write-lock on force-close", th);
-          error = th;
+          error = (error == null) ? th : error;
         }
       }
+
       if (error != null) {
-        try {
-          internalFactory.abortWriteTransaction();
-          externalFactory.abortWriteTransaction();
-        } catch (Throwable th) {
-          logger.error("Error aborting writeTransaction", th);
-        }
         if (error instanceof MulgaraTransactionException) {
           throw (MulgaraTransactionException)error;
         } else {




More information about the Mulgara-svn mailing list