[exo-jcr-commits] exo-jcr SVN: r1428 - jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent.

do-not-reply at jboss.org do-not-reply at jboss.org
Sat Jan 16 05:59:13 EST 2010


Author: pnedonosko
Date: 2010-01-16 05:59:13 -0500 (Sat, 16 Jan 2010)
New Revision: 1428

Modified:
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
Log:
EXOJCR-405 use transaction suspend/resume for JCR storage dedicated XA commit

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java	2010-01-16 10:34:39 UTC (rev 1427)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java	2010-01-16 10:59:13 UTC (rev 1428)
@@ -406,86 +406,132 @@
       {
          super.save(changesLog);
 
-         // notify listeners after transaction commit         
-         notifySaveItems(changesLog, false);              
+         // notify listeners after storage commit
+         notifySaveItems(changesLog, false);
       }
       else
       {
          try
          {
-            if (transactionManager.getStatus() == Status.STATUS_COMMITTING)
+            // Care about dedicated XA transaction for storage save:
+            // suspend current ransaction and create one new for the JCR storage (cache etc.)
+            // after the new transaction done we'll resume the current.
+            Transaction current = transactionManager.suspend();
+            try
             {
-               // The JCR session has been enrolled into a XA Transaction, the method applyChanges must be called in another thread since the operations
-               // that we do into the cache are not allowed within the current Transaction, so to do it in another Transaction we need to call the method
-               // from another Thread
-               final AtomicReference<Exception> exception = new AtomicReference<Exception>();
-               final CountDownLatch doneSignal = new CountDownLatch(1);
-               Thread t = new Thread()
+               saveInTransaction(changesLog);
+
+               // notify listeners after transaction commit but before the current resume!
+               try
                {
-                  public void run()
+                  notifySaveItems(changesLog, false);
+               }
+               catch (Throwable th)
+               {
+                  // TODO XA layer can throws runtime exceptions
+                  throw new RepositoryException(th);
+               }
+            }
+            finally
+            {
+               if (current != null)
+               {
+                  try
                   {
-                     try
-                     {
-                        applyChanges(changesLog);
-                     }
-                     catch (Exception e)
-                     {
-                        exception.set(e);
-                     }
-                     finally
-                     {
-                        doneSignal.countDown();
-                     }
+                     transactionManager.resume(current);
                   }
-               };
-               t.start();
-               doneSignal.await();
-               Exception e = exception.get();
-               if (e != null)
-               {
-                  if (e instanceof RepositoryException)
+                  catch (InvalidTransactionException e)
                   {
-                     throw (RepositoryException)e;                     
+                     throw new RepositoryException(e);
                   }
-                  else
+                  catch (IllegalStateException e)
                   {
-                     throw new RuntimeException(e);
+                     throw new RepositoryException(e);
                   }
                }
             }
-            else
-            {
-               // Normal Transaction
-               applyChanges(changesLog);
-            }
          }
-         catch (RepositoryException e)
-         {
-            throw e;
-         }
-         catch (InterruptedException e)
-         {
-            throw new RepositoryException(e.getLocalizedMessage(), e.getCause());
-         }
          catch (SystemException e)
          {
-            throw new RepositoryException(e.getLocalizedMessage(), e.getCause());
+            throw new RepositoryException(e);
          }
+
+         // TODO to do not commit in curr thread (i.e. curr tx)
+         //         try
+         //         {
+         //            if (transactionManager.getStatus() == Status.STATUS_COMMITTING)
+         //            {
+         //               // The JCR session has been enrolled into a XA Transaction, the method applyChanges must be called in another thread since the operations
+         //               // that we do into the cache are not allowed within the current Transaction, so to do it in another Transaction we need to call the method
+         //               // from another Thread
+         //               final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+         //               final CountDownLatch doneSignal = new CountDownLatch(1);
+         //               Thread t = new Thread()
+         //               {
+         //                  public void run()
+         //                  {
+         //                     try
+         //                     {
+         //                        applyChanges(changesLog);
+         //                     }
+         //                     catch (Exception e)
+         //                     {
+         //                        exception.set(e);
+         //                     }
+         //                     finally
+         //                     {
+         //                        doneSignal.countDown();
+         //                     }
+         //                  }
+         //               };
+         //               t.start();
+         //               doneSignal.await();
+         //               Exception e = exception.get();
+         //               if (e != null)
+         //               {
+         //                  if (e instanceof RepositoryException)
+         //                  {
+         //                     throw (RepositoryException)e;                     
+         //                  }
+         //                  else
+         //                  {
+         //                     throw new RuntimeException(e);
+         //                  }
+         //               }
+         //            }
+         //            else
+         //            {
+         //               // Normal Transaction
+         //               applyChanges(changesLog);
+         //            }
+         //         }
+         //         catch (RepositoryException e)
+         //         {
+         //            throw e;
+         //         }
+         //         catch (InterruptedException e)
+         //         {
+         //            throw new RepositoryException(e.getLocalizedMessage(), e.getCause());
+         //         }
+         //         catch (SystemException e)
+         //         {
+         //            throw new RepositoryException(e.getLocalizedMessage(), e.getCause());
+         //         }
       }
-   } 
+   }
 
    /**
-    * Apply all the current changes
+    * Apply all the changes in new XA transaction. This save should run in dedicated XA transaction, i.e. only JCR storage stuff should be involved to.
     */
-   private void applyChanges(ItemStateChangesLog changesLog) throws RepositoryException
+   private void saveInTransaction(ItemStateChangesLog changesLog) throws RepositoryException
    {
       try
       {
-         transactionManager.begin();
+         transactionManager.begin(); // start new global tx
          cache.beginTransaction(); // TODO keep it into the cache impl
          super.save(changesLog);
          cache.commitTransaction();
-         transactionManager.commit();
+         transactionManager.commit(); // commit global tx
       }
       catch (RollbackException e)
       {
@@ -497,7 +543,7 @@
          try
          {
             cache.rollbackTransaction();
-            transactionManager.rollback();
+            transactionManager.rollback(); // rollback global tx
          }
          catch (Exception e1)
          {
@@ -576,9 +622,6 @@
 
          throw new RepositoryException(e);
       }
-
-      // notify listeners after transaction commit         
-      notifySaveItems(changesLog, false);      
    }
 
    /**



More information about the exo-jcr-commits mailing list