[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