Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2013-08-05 14:24:49 -0400
committerEike Stepper2013-08-05 14:24:49 -0400
commit903a2169001c44b724759e8ed66517c831a2fbdb (patch)
treedcd2fc530042d4723bc2d82924c85e77c11a17c0
parent4f29ce12ff912157d32dd166f3a6e8aeac71d2a9 (diff)
downloadcdo-bugs/411939.tar.gz
cdo-bugs/411939.tar.xz
cdo-bugs/411939.zip
[411939] CDOSessionImpl can "freeze" during invalidation reorderingbugs/411939
https://bugs.eclipse.org/bugs/show_bug.cgi?id=411939
-rw-r--r--plugins/org.eclipse.emf.cdo.server/META-INF/MANIFEST.MF22
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TimeStampAuthority.java76
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF48
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338779_Test.java77
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_341995_Test.java38
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_390185_Test.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java450
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java42
11 files changed, 438 insertions, 339 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server/META-INF/MANIFEST.MF
index 98aad84a7c..55a6496d9a 100644
--- a/plugins/org.eclipse.emf.cdo.server/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.server/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.emf.cdo.server;singleton:=true
-Bundle-Version: 4.2.0.qualifier
+Bundle-Version: 4.2.1.qualifier
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -10,18 +10,18 @@ Bundle-Activator: org.eclipse.emf.cdo.internal.server.bundle.OM$Activator
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ClassPath: .
Require-Bundle: org.eclipse.emf.cdo;bundle-version="[4.0.0,5.0.0)";visibility:=reexport
-Export-Package: org.eclipse.emf.cdo.internal.server;version="4.2.0";
+Export-Package: org.eclipse.emf.cdo.internal.server;version="4.2.1";
x-friends:="org.eclipse.emf.cdo.server.db,
org.eclipse.emf.cdo.server.net4j,
org.eclipse.emf.cdo.tests,
org.eclipse.emf.cdo.workspace,
org.eclipse.emf.cdo.server.hibernate",
- org.eclipse.emf.cdo.internal.server.bundle;version="4.2.0";x-internal:=true,
- org.eclipse.emf.cdo.internal.server.embedded;version="4.2.0";x-friends:="org.eclipse.emf.cdo.tests",
- org.eclipse.emf.cdo.internal.server.mem;version="4.2.0";x-friends:="org.eclipse.emf.cdo.tests",
- org.eclipse.emf.cdo.internal.server.messages;version="4.2.0";x-internal:=true,
- org.eclipse.emf.cdo.internal.server.syncing;version="4.2.0";x-friends:="org.eclipse.emf.cdo.tests",
- org.eclipse.emf.cdo.server;version="4.2.0",
- org.eclipse.emf.cdo.server.embedded;version="4.2.0",
- org.eclipse.emf.cdo.server.mem;version="4.2.0",
- org.eclipse.emf.cdo.spi.server;version="4.2.0"
+ org.eclipse.emf.cdo.internal.server.bundle;version="4.2.1";x-internal:=true,
+ org.eclipse.emf.cdo.internal.server.embedded;version="4.2.1";x-friends:="org.eclipse.emf.cdo.tests",
+ org.eclipse.emf.cdo.internal.server.mem;version="4.2.1";x-friends:="org.eclipse.emf.cdo.tests",
+ org.eclipse.emf.cdo.internal.server.messages;version="4.2.1";x-internal:=true,
+ org.eclipse.emf.cdo.internal.server.syncing;version="4.2.1";x-friends:="org.eclipse.emf.cdo.tests",
+ org.eclipse.emf.cdo.server;version="4.2.1",
+ org.eclipse.emf.cdo.server.embedded;version="4.2.1",
+ org.eclipse.emf.cdo.server.mem;version="4.2.1",
+ org.eclipse.emf.cdo.spi.server;version="4.2.1"
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
index 14f804b5cd..ab8f065d15 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
@@ -225,6 +225,7 @@ public class Session extends Container<IView> implements InternalSession
this.lockNotificationMode = lockNotificationMode;
}
+ @Deprecated
public long getLastUpdateTime()
{
synchronized (lastUpdateTimeLock)
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TimeStampAuthority.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TimeStampAuthority.java
index b31401ef8c..6d3c997efb 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TimeStampAuthority.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TimeStampAuthority.java
@@ -33,17 +33,21 @@ class TimeStampAuthority
private InternalRepository repository;
/**
- * Holds the timestamp that was issued in response to the last call to {@link #createTimestamp()}
+ * Holds the <i>begin</i> timestamp that was issued in response to the last call to {@link #startCommit(long, OMMonitor)}.
+ * <p>
+ * Synchronized on <code>TimeStampAuthority.this</code>.
*/
@ExcludeFromDump
private transient long lastIssuedTimeStamp = CDOBranchPoint.UNSPECIFIED_DATE;
/**
- * Holds the timestamp that was last reported finished by a call to {@link #endCommit(long)}
+ * Holds the <i>begin</i> timestamp that was last reported finished by a call to {@link #endCommit(long)}.
+ * <p>
+ * Synchronized on <code>lastFinishedTimeStampLock</code>.
*/
private long lastFinishedTimeStamp;
- private LastCommitTimeStampLock lastCommitTimeStampLock = new LastCommitTimeStampLock();
+ private LastCommitTimeStampLock lastFinishedTimeStampLock = new LastCommitTimeStampLock();
private boolean strictOrdering; // TODO (CD) Should be a repo property
@@ -76,11 +80,7 @@ class TimeStampAuthority
synchronized long[] startCommit(long timeStampOverride, OMMonitor monitor)
{
monitor.begin();
-
- if (strictOrdering)
- {
- strictOrderingLock.lock();
- }
+ lockIfNeeded();
try
{
@@ -100,10 +100,11 @@ class TimeStampAuthority
now = timeStampOverride;
}
+ long previousTimeStamp = lastIssuedTimeStamp;
lastIssuedTimeStamp = now;
- runningTransactions.add(lastIssuedTimeStamp);
- return new long[] { lastIssuedTimeStamp, getLastFinishedTimeStamp() };
+ runningTransactions.add(now);
+ return new long[] { now, previousTimeStamp };
}
finally
{
@@ -124,41 +125,35 @@ class TimeStampAuthority
// of the runningTransactions. Since both sets are sorted, we only need to compare the heads.
long oldestRunning = runningTransactions.isEmpty() ? Long.MAX_VALUE : runningTransactions.get(0);
long oldestFinished;
- synchronized (lastCommitTimeStampLock)
+ synchronized (lastFinishedTimeStampLock)
{
long oldValue = lastFinishedTimeStamp;
while (!finishedTransactions.isEmpty() && (oldestFinished = finishedTransactions.first()) < oldestRunning)
{
finishedTransactions.remove(oldestFinished);
- internalSetLastFinished(oldestFinished);
+ setLastFinishedTimeStampUnsynced(oldestFinished);
}
// If we actually changed the lastFinishedTimeStamp, we need to notify waiting threads
if (lastFinishedTimeStamp != oldValue)
{
- lastCommitTimeStampLock.notifyAll();
+ lastFinishedTimeStampLock.notifyAll();
}
}
- if (strictOrdering)
- {
- strictOrderingLock.unlock();
- }
+ unlockIfNeeded();
}
synchronized void failCommit(long timeStamp)
{
- if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) // Exclude problems before TransactionCommitContext.setTimeStamp()
+ // Exclude problems before TransactionCommitContext.setTimeStamp()
+ if (timeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
{
- if (!runningTransactions.remove(timeStamp))
- {
- throw new IllegalArgumentException("Cannot fail transaction with unknown timestamp " + timeStamp);
- }
+ unlockIfNeeded();
}
-
- if (strictOrdering)
+ else
{
- strictOrderingLock.unlock();
+ endCommit(timeStamp);
}
}
@@ -183,11 +178,11 @@ class TimeStampAuthority
long waitForCommit(long timeout)
{
- synchronized (lastCommitTimeStampLock)
+ synchronized (lastFinishedTimeStampLock)
{
try
{
- lastCommitTimeStampLock.wait(timeout);
+ lastFinishedTimeStampLock.wait(timeout);
}
catch (Exception ignore)
{
@@ -199,22 +194,39 @@ class TimeStampAuthority
void setLastFinishedTimeStamp(long lastCommitTimeStamp)
{
- synchronized (lastCommitTimeStampLock)
+ synchronized (lastFinishedTimeStampLock)
{
- if (lastFinishedTimeStamp < lastCommitTimeStamp)
+ if (lastCommitTimeStamp > lastFinishedTimeStamp)
{
- internalSetLastFinished(lastCommitTimeStamp);
- lastCommitTimeStampLock.notifyAll();
+ lastIssuedTimeStamp = lastCommitTimeStamp;
+ setLastFinishedTimeStampUnsynced(lastCommitTimeStamp);
+ lastFinishedTimeStampLock.notifyAll();
}
}
}
- private void internalSetLastFinished(long lastCommitTimeStamp)
+ private void setLastFinishedTimeStampUnsynced(long lastCommitTimeStamp)
{
lastFinishedTimeStamp = lastCommitTimeStamp;
repository.getStore().setLastCommitTime(lastFinishedTimeStamp);
}
+ private void lockIfNeeded()
+ {
+ if (strictOrdering)
+ {
+ strictOrderingLock.lock();
+ }
+ }
+
+ private void unlockIfNeeded()
+ {
+ if (strictOrdering)
+ {
+ strictOrderingLock.unlock();
+ }
+ }
+
/**
* A separate class for better monitor debugging.
*
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java
index c5c7931d69..38a511338d 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java
@@ -20,7 +20,7 @@ import org.eclipse.net4j.util.container.IContainer;
/**
* The server-side representation of a client {@link CDOSession session}.
- *
+ *
* @author Eike Stepper
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
@@ -43,7 +43,9 @@ public interface ISession extends CDOCommonSession, IContainer<IView>
/**
* @since 4.0
+ * @deprecated The return value of this method can not be relied upon to be strictly ordered!
*/
+ @Deprecated
public long getLastUpdateTime();
/**
diff --git a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF
index 6bf445139b..6be9e09234 100644
--- a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.emf.cdo.tests;singleton:=true
-Bundle-Version: 4.0.200.qualifier
+Bundle-Version: 4.0.201.qualifier
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -36,28 +36,28 @@ Require-Bundle: org.eclipse.net4j.tests;bundle-version="[4.0.0,5.0.0)";visibilit
org.eclipse.emf.cdo.server.admin;bundle-version="[4.1.0,5.0.0)";visibility:=reexport,
org.eclipse.gmf.runtime.notation;bundle-version="[1.5.0,2.0.0)";visibility:=reexport,
org.eclipse.ocl.ecore;bundle-version="[3.0.0,4.0.0)"
-Export-Package: base;version="4.0.200",
- base.impl;version="4.0.200",
- base.util;version="4.0.200",
- derived;version="4.0.200",
- derived.impl;version="4.0.200",
- derived.util;version="4.0.200",
- interface_;version="4.0.200",
- interface_.impl;version="4.0.200",
- interface_.util;version="4.0.200",
- org.eclipse.emf.cdo.tests;version="4.0.200",
- org.eclipse.emf.cdo.tests.bugzilla;version="4.0.200",
- org.eclipse.emf.cdo.tests.bundle;version="4.0.200";x-internal:=true,
- org.eclipse.emf.cdo.tests.config;version="4.0.200",
- org.eclipse.emf.cdo.tests.config.impl;version="4.0.200",
- org.eclipse.emf.cdo.tests.defs;version="4.0.200",
- org.eclipse.emf.cdo.tests.offline;version="4.0.200",
- org.eclipse.emf.cdo.tests.performance;version="4.0.200",
- org.eclipse.emf.cdo.tests.performance.framework;version="4.0.200",
- org.eclipse.emf.cdo.tests.revisioncache;version="4.0.200",
- org.eclipse.emf.cdo.tests.util;version="4.0.200",
- reference;version="4.0.200",
- reference.impl;version="4.0.200";
+Export-Package: base;version="4.0.201",
+ base.impl;version="4.0.201",
+ base.util;version="4.0.201",
+ derived;version="4.0.201",
+ derived.impl;version="4.0.201",
+ derived.util;version="4.0.201",
+ interface_;version="4.0.201",
+ interface_.impl;version="4.0.201",
+ interface_.util;version="4.0.201",
+ org.eclipse.emf.cdo.tests;version="4.0.201",
+ org.eclipse.emf.cdo.tests.bugzilla;version="4.0.201",
+ org.eclipse.emf.cdo.tests.bundle;version="4.0.201";x-internal:=true,
+ org.eclipse.emf.cdo.tests.config;version="4.0.201",
+ org.eclipse.emf.cdo.tests.config.impl;version="4.0.201",
+ org.eclipse.emf.cdo.tests.defs;version="4.0.201",
+ org.eclipse.emf.cdo.tests.offline;version="4.0.201",
+ org.eclipse.emf.cdo.tests.performance;version="4.0.201",
+ org.eclipse.emf.cdo.tests.performance.framework;version="4.0.201",
+ org.eclipse.emf.cdo.tests.revisioncache;version="4.0.201",
+ org.eclipse.emf.cdo.tests.util;version="4.0.201",
+ reference;version="4.0.201",
+ reference.impl;version="4.0.201";
x-friends:="org.eclipse.emf.cdo.dawn.tests,
org.eclipse.emf.cdo.tests.db,
org.eclipse.emf.cdo.tests.db4o,
@@ -66,5 +66,5 @@ Export-Package: base;version="4.0.200",
org.eclipse.emf.cdo.tests.objectivity,
org.eclipse.emf.cdo.tests.ui,
org.eclipse.emf.cdo.tests.mongodb",
- reference.util;version="4.0.200"
+ reference.util;version="4.0.201"
Eclipse-BuddyPolicy: dependent
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338779_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338779_Test.java
index 617404611f..f525ed643c 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338779_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338779_Test.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Caspar De Groot - initial API and implementation
*/
@@ -31,10 +31,30 @@ import java.util.Date;
*/
public class Bugzilla_338779_Test extends AbstractCDOTest
{
- private void test(PassiveUpdateMode passiveUpdateMode) throws CommitException
+ public void test_refresh() throws CommitException
+ {
+ runTest(null);
+ }
+
+ public void test_passiveUpdate_invalidations() throws CommitException
+ {
+ runTest(PassiveUpdateMode.INVALIDATIONS);
+ }
+
+ public void test_passiveUpdate_changes() throws CommitException
+ {
+ runTest(PassiveUpdateMode.CHANGES);
+ }
+
+ public void test_passiveUpdate_additions() throws CommitException
+ {
+ runTest(PassiveUpdateMode.ADDITIONS);
+ }
+
+ private void runTest(PassiveUpdateMode passiveUpdateMode) throws CommitException
{
final CDOSession session = openSession();
- CDOTransaction tx = session.openTransaction();
+ CDOTransaction transaction = session.openTransaction();
if (passiveUpdateMode != null)
{
session.options().setPassiveUpdateEnabled(true);
@@ -44,15 +64,16 @@ public class Bugzilla_338779_Test extends AbstractCDOTest
{
session.options().setPassiveUpdateEnabled(false);
}
- CDOResource r1 = tx.createResource(getResourcePath("/r1")); //$NON-NLS-1$
- PurchaseOrder po1 = getModel1Factory().createPurchaseOrder();
- po1.setDate(new Date());
- r1.getContents().add(po1);
+ CDOResource resource1 = transaction.createResource(getResourcePath("/r1")); //$NON-NLS-1$
+
+ PurchaseOrder purchaseOrder1 = getModel1Factory().createPurchaseOrder();
+ purchaseOrder1.setDate(new Date());
+ resource1.getContents().add(purchaseOrder1);
- tx.commit();
+ transaction.commit();
- check(po1, session);
+ check(purchaseOrder1, session);
long timestamp = doSecondSession();
if (passiveUpdateMode != null)
@@ -62,7 +83,7 @@ public class Bugzilla_338779_Test extends AbstractCDOTest
if (passiveUpdateMode == PassiveUpdateMode.INVALIDATIONS)
{
// Read something on the object to force load
- po1.getDate();
+ purchaseOrder1.getDate();
}
}
else
@@ -70,32 +91,12 @@ public class Bugzilla_338779_Test extends AbstractCDOTest
session.refresh();
}
- check(po1, session);
+ check(purchaseOrder1, session);
- tx.close();
+ transaction.close();
session.close();
}
- public void test_refresh() throws CommitException
- {
- test(null);
- }
-
- public void test_passiveUpdate_invalidations() throws CommitException
- {
- test(PassiveUpdateMode.INVALIDATIONS);
- }
-
- public void test_passiveUpdate_changes() throws CommitException
- {
- test(PassiveUpdateMode.CHANGES);
- }
-
- public void test_passiveUpdate_additions() throws CommitException
- {
- test(PassiveUpdateMode.ADDITIONS);
- }
-
private void check(EObject eObject, CDOSession session)
{
CDOObject obj = CDOUtil.getCDOObject(eObject);
@@ -109,15 +110,15 @@ public class Bugzilla_338779_Test extends AbstractCDOTest
private long doSecondSession() throws CommitException
{
CDOSession session = openSession();
- CDOTransaction tx = session.openTransaction();
- CDOResource r1 = tx.getResource(getResourcePath("/r1")); //$NON-NLS-1$
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource1 = transaction.getResource(getResourcePath("/r1")); //$NON-NLS-1$
// Change the purchaseOrder
- PurchaseOrder po1 = (PurchaseOrder)r1.getContents().get(0);
- po1.setDate(new Date());
+ PurchaseOrder purchaseOrder1 = (PurchaseOrder)resource1.getContents().get(0);
+ purchaseOrder1.setDate(new Date());
- CDOCommitInfo commitInfo = tx.commit();
- tx.close();
+ CDOCommitInfo commitInfo = transaction.commit();
+ transaction.close();
session.close();
return commitInfo.getTimeStamp();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_341995_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_341995_Test.java
index 20412b07a4..950078044a 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_341995_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_341995_Test.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Caspar De Groot - initial API and implementation
*/
@@ -25,8 +25,8 @@ import org.eclipse.emf.cdo.util.CommitException;
import java.util.concurrent.TimeUnit;
/**
- * See bug 341995.
- *
+ * Bug 341995:
+ *
* @author Caspar De Groot
*/
public class Bugzilla_341995_Test extends AbstractCDOTest
@@ -34,16 +34,16 @@ public class Bugzilla_341995_Test extends AbstractCDOTest
public void test() throws Exception
{
CDOSession session = openSession();
- CDOTransaction tx = session.openTransaction();
- CDOResource resource = tx.createResource(getResourcePath("test"));
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(getResourcePath("test"));
Model1Factory factory = getModel1Factory();
- Category cat = factory.createCategory();
- resource.getContents().add(cat);
- tx.commit();
+ Category category = factory.createCategory();
+ resource.getContents().add(category);
+ transaction.commit();
- CDOObject cdoCat = CDOUtil.getCDOObject(cat);
- msg(cdoCat.cdoRevision().getVersion());
+ CDOObject cdoCategory = CDOUtil.getCDOObject(category);
+ msg(cdoCategory.cdoRevision().getVersion());
long delay = 2000L;
@@ -60,14 +60,14 @@ public class Bugzilla_341995_Test extends AbstractCDOTest
// Attempt the lock; this must block for a while, because it needs to receive
// the commitNotification from the commit in the other session, which we are
// artificially delaying
- cdoCat.cdoWriteLock().lock(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
+ cdoCategory.cdoWriteLock().lock(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
long timeTaken = System.currentTimeMillis() - time1;
// We verify that there really was a delay
- assertEquals("timeTaken == " + timeTaken, true, timeTaken >= delay);
+ assertEquals("timeTaken == " + timeTaken, true, timeTaken >= delay - 10);
- tx.close();
+ transaction.close();
session.close();
}
finally
@@ -83,17 +83,17 @@ public class Bugzilla_341995_Test extends AbstractCDOTest
public void run()
{
CDOSession session = openSession();
- CDOTransaction tx = session.openTransaction();
- CDOResource resource = tx.getResource(getResourcePath("test"));
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.getResource(getResourcePath("test"));
- Category cat = (Category)resource.getContents().get(0);
- cat.setName("dirty");
+ Category category = (Category)resource.getContents().get(0);
+ category.setName("dirty");
CDOCommitInfo info;
try
{
- info = tx.commit();
+ info = transaction.commit();
}
catch (CommitException ex)
{
@@ -102,7 +102,7 @@ public class Bugzilla_341995_Test extends AbstractCDOTest
msg(info.getTimeStamp());
- tx.close();
+ transaction.close();
session.close();
}
};
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_390185_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_390185_Test.java
index cb06c5392f..b81aa684e9 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_390185_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_390185_Test.java
@@ -15,7 +15,9 @@ import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
-import org.eclipse.emf.cdo.util.CommitException;
+import org.eclipse.emf.cdo.util.CommitConflictException;
+
+import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
import java.util.ArrayList;
import java.util.List;
@@ -24,17 +26,17 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
- * Bug 390185.
+ * Bug 390185: Deadlock on multiple concurrent transactions.
*
* @author Eike Stepper
*/
public class Bugzilla_390185_Test extends AbstractCDOTest
{
- private static final int THREADS = 5;
+ private static final int THREADS = 4;
- private static final int TRANSACTIONS_PER_THREAD = 100;
+ private static final int TRANSACTIONS_PER_THREAD = 40;
- public void testIvalidationDeadlock() throws Exception
+ public void testInvalidationDeadlock() throws Exception
{
CDOSession session = openSession();
@@ -48,7 +50,7 @@ public class Bugzilla_390185_Test extends AbstractCDOTest
if (!latch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS))
{
- throw new TimeoutException();
+ throw new TimeoutException("Not all actory finished in time");
}
}
@@ -80,6 +82,7 @@ public class Bugzilla_390185_Test extends AbstractCDOTest
CDOTransaction transaction = session.openTransaction();
attemptCommit(transaction);
transaction.close();
+ ConcurrencyUtil.sleep(2);
}
latch.countDown();
@@ -102,7 +105,7 @@ public class Bugzilla_390185_Test extends AbstractCDOTest
break;
}
}
- catch (CommitException ex)
+ catch (CommitConflictException ex)
{
transaction.rollback();
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java
index 8dab040d42..e686514ebc 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java
@@ -703,7 +703,7 @@ public class OfflineTest extends AbstractSyncingTest
getOfflineConfig().startMasterTransport();
waitForOnline(clone);
- sleep(1000);
+ sleep(3000);
IEvent[] sessionEvents = sessionListener.getEvents();
assertEquals(4, sessionEvents.length); // 3x repo state change + 1x invalidation
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
index b783e08b74..e20477f37b 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
@@ -47,6 +47,7 @@ import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
@@ -93,7 +94,7 @@ import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.concurrent.IRWLockManager;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.concurrent.IRWOLockManager;
-import org.eclipse.net4j.util.concurrent.QueueRunner;
+import org.eclipse.net4j.util.concurrent.QueueRunner2;
import org.eclipse.net4j.util.concurrent.RWOLockManager;
import org.eclipse.net4j.util.event.Event;
import org.eclipse.net4j.util.event.EventUtil;
@@ -105,6 +106,7 @@ import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.log.OMLogger;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.options.OptionsEvent;
import org.eclipse.net4j.util.security.IPasswordCredentialsProvider;
@@ -145,6 +147,8 @@ import java.util.Set;
*/
public abstract class CDOSessionImpl extends CDOTransactionContainerImpl implements InternalCDOSession
{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SESSION, CDOSessionImpl.class);
+
private ExceptionHandler exceptionHandler;
private CDOIDGenerator idGenerator;
@@ -180,9 +184,7 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
private CDOSession.Options options = createOptions();
- private OutOfSequenceInvalidations outOfSequenceInvalidations = new OutOfSequenceInvalidations();
-
- private QueueRunner invalidationRunner;
+ private Invalidator invalidator = new Invalidator();
private CDORepositoryInfo repositoryInfo;
@@ -1045,165 +1047,25 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
}
}
- @Deprecated
- public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
+ public Object startLocalCommit()
{
- invalidate(commitInfo, sender, true);
+ return invalidator.startLocalCommit();
}
- public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache)
+ public void endLocalCommit(Object token)
{
- long previousTimeStamp = commitInfo.getPreviousTimeStamp();
- long lastUpdateTime = getLastUpdateTime();
-
- if (previousTimeStamp < lastUpdateTime)
- {
- previousTimeStamp = lastUpdateTime;
- }
-
- synchronized (outOfSequenceInvalidations)
- {
- outOfSequenceInvalidations.put(previousTimeStamp, new OutOfSequenceInvalidation(commitInfo, sender,
- clearResourcePathCache));
- }
-
- long nextPreviousTimeStamp = lastUpdateTime;
- for (;;)
- {
- Runnable invalidationRunnable = null;
- synchronized (outOfSequenceInvalidations)
- {
- OutOfSequenceInvalidation currentInvalidation = outOfSequenceInvalidations.remove(nextPreviousTimeStamp);
- if (currentInvalidation == null)
- {
- // If we don't have the invalidation that follows the last one we processed,
- // then there is nothing we can do right now
- break;
- }
-
- final CDOCommitInfo currentCommitInfo = currentInvalidation.getCommitInfo();
- final InternalCDOTransaction currentSender = currentInvalidation.getSender();
- final boolean currentClearResourcePathCache = currentInvalidation.isClearResourcePathCache();
- nextPreviousTimeStamp = currentCommitInfo.getTimeStamp();
-
- invalidationRunnable = new Runnable()
- {
- public void run()
- {
- invalidateOrdered(currentCommitInfo, currentSender, currentClearResourcePathCache);
- }
- };
-
- if (sender == null)
- {
- QueueRunner invalidationRunner = getInvalidationRunner();
- invalidationRunner.addWork(invalidationRunnable);
- invalidationRunnable = null;
- }
- }
-
- if (invalidationRunnable != null)
- {
- invalidationRunnable.run();
- }
- }
- }
-
- /**
- * This method is synchronized on outOfSequenceInvalidations by the caller!
- */
- private QueueRunner getInvalidationRunner()
- {
- if (invalidationRunner == null)
- {
- invalidationRunner = new QueueRunner()
- {
- @Override
- protected void noWork(WorkContext context)
- {
- if (isClosed())
- {
- context.terminate();
- }
- }
-
- @Override
- protected String getThreadName()
- {
- return "CDOSessionInvalidationRunner-" + CDOSessionImpl.this;
- }
- };
-
- invalidationRunner.activate();
- }
-
- return invalidationRunner;
- }
-
- private void invalidateOrdered(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache)
- {
- Map<CDOID, InternalCDORevision> oldRevisions = null;
- boolean success = commitInfo.getBranch() != null;
- if (success)
- {
- oldRevisions = reviseRevisions(commitInfo);
- }
-
- if (options.isPassiveUpdateEnabled())
- {
- setLastUpdateTime(commitInfo.getTimeStamp());
- }
-
- if (success)
- {
- fireInvalidationEvent(sender, commitInfo);
- commitInfoManager.notifyCommitInfoHandlers(commitInfo);
- }
-
- for (InternalCDOView view : getViews())
- {
- if (view != sender)
- {
- invalidateView(commitInfo, view, oldRevisions, clearResourcePathCache);
- }
- else
- {
- view.setLastUpdateTime(commitInfo.getTimeStamp());
- }
- }
+ invalidator.endLocalCommit(token);
}
- private void invalidateView(CDOCommitInfo commitInfo, InternalCDOView view,
- Map<CDOID, InternalCDORevision> oldRevisions, boolean clearResourcePathCache)
+ @Deprecated
+ public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
{
- try
- {
- CDOBranch branch = commitInfo.getBranch();
- long lastUpdateTime = commitInfo.getTimeStamp();
- List<CDORevisionKey> allChangedObjects = commitInfo.getChangedObjects();
- List<CDOIDAndVersion> allDetachedObjects = commitInfo.getDetachedObjects();
- view.invalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions, true,
- clearResourcePathCache);
- }
- catch (RuntimeException ex)
- {
- if (view.isActive())
- {
- OM.LOG.error(ex);
- }
- else
- {
- OM.LOG.info(Messages.getString("CDOSessionImpl.1")); //$NON-NLS-1$
- }
- }
+ invalidate(commitInfo, sender, true);
}
- /**
- * @since 2.0
- */
- public void fireInvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
+ public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache)
{
- fireEvent(new InvalidationEvent(sender, commitInfo));
+ invalidator.reorderInvalidations(commitInfo, sender, clearResourcePathCache);
}
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter)
@@ -1393,6 +1255,7 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
protected void doActivate() throws Exception
{
super.doActivate();
+ LifecycleUtil.activate(invalidator);
InternalCDORemoteSessionManager remoteSessionManager = new CDORemoteSessionManagerImpl();
remoteSessionManager.setLocalSession(this);
@@ -1406,11 +1269,9 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
@Override
protected void doDeactivate() throws Exception
{
+ LifecycleUtil.deactivate(invalidator);
super.doDeactivate();
- LifecycleUtil.deactivate(invalidationRunner);
- outOfSequenceInvalidations.clear();
-
unhookSessionProtocol();
CDORemoteSessionManager remoteSessionManager = getRemoteSessionManager();
@@ -1455,49 +1316,6 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
/**
* @author Eike Stepper
- */
- private static final class OutOfSequenceInvalidation
- {
- private CDOCommitInfo commitInfo;
-
- private InternalCDOTransaction sender;
-
- private boolean clearResourcePathCache;
-
- public OutOfSequenceInvalidation(CDOCommitInfo commitInfo, InternalCDOTransaction sender,
- boolean clearResourcePathCache)
- {
- this.commitInfo = commitInfo;
- this.sender = sender;
- this.clearResourcePathCache = clearResourcePathCache;
- }
-
- public CDOCommitInfo getCommitInfo()
- {
- return commitInfo;
- }
-
- public InternalCDOTransaction getSender()
- {
- return sender;
- }
-
- public boolean isClearResourcePathCache()
- {
- return clearResourcePathCache;
- }
- }
-
- /**
- * @author Eike Stepper
- */
- private static final class OutOfSequenceInvalidations extends HashMap<Long, OutOfSequenceInvalidation>
- {
- private static final long serialVersionUID = 1L;
- }
-
- /**
- * @author Eike Stepper
* @since 2.0
*/
protected class OptionsImpl extends Notifier implements Options
@@ -1829,6 +1647,240 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
/**
* @author Eike Stepper
*/
+ private class Invalidator extends QueueRunner2<Invalidation>
+ {
+ private static final boolean DEBUG = false;
+
+ private final Set<Object> unfinishedLocalCommits = new HashSet<Object>();
+
+ private final List<Invalidation> reorderQueue = new ArrayList<Invalidation>();
+
+ public Invalidator()
+ {
+ }
+
+ public synchronized Object startLocalCommit()
+ {
+ if (!isActive())
+ {
+ return null;
+ }
+
+ final String threadName = Thread.currentThread().getName();
+ Object token = new Object()
+ {
+ @Override
+ public String toString()
+ {
+ return threadName;
+ }
+ };
+
+ unfinishedLocalCommits.add(token);
+ return token;
+ }
+
+ public synchronized void endLocalCommit(Object token)
+ {
+ unfinishedLocalCommits.remove(token);
+ }
+
+ public synchronized void reorderInvalidations(CDOCommitInfo commitInfo, InternalCDOTransaction sender,
+ boolean clearResourcePathCache)
+ {
+ if (!isActive())
+ {
+ return;
+ }
+
+ Invalidation invalidation = new Invalidation(commitInfo, sender, clearResourcePathCache);
+ reorderQueue.add(invalidation);
+ Collections.sort(reorderQueue);
+
+ if (DEBUG)
+ {
+ IOUtil.OUT().println(
+ CDOSessionImpl.this + " [" + getLastUpdateTime() % 10000 + "] " + commitInfo.getPreviousTimeStamp() % 10000
+ + " --> " + commitInfo.getTimeStamp() % 10000 + " reorderQueue=" + reorderQueue
+ + " unfinishedLocalCommits=" + unfinishedLocalCommits);
+ }
+
+ scheduleInvalidations();
+ }
+
+ public synchronized void scheduleInvalidations()
+ {
+ while (!reorderQueue.isEmpty() && canProcess(reorderQueue.get(0)))
+ {
+ Invalidation invalidation0 = reorderQueue.remove(0);
+ addWork(invalidation0);
+ }
+ }
+
+ protected boolean canProcess(Invalidation invalidation)
+ {
+ if (options().isPassiveUpdateEnabled())
+ {
+ long previousTimeStamp = invalidation.getPreviousTimeStamp();
+ long lastUpdateTime = getLastUpdateTime();
+ return previousTimeStamp <= lastUpdateTime; // Can be smaller in replication scenarios
+ }
+
+ return unfinishedLocalCommits.size() == 1; // Ourselves
+ }
+
+ @Override
+ protected void noWork(WorkContext context)
+ {
+ if (isClosed())
+ {
+ context.terminate();
+ }
+ }
+
+ @Override
+ protected String getThreadName()
+ {
+ return "CDOSessionInvalidator-" + CDOSessionImpl.this;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class Invalidation implements Comparable<Invalidation>, Runnable
+ {
+ private final CDOCommitInfo commitInfo;
+
+ private final InternalCDOTransaction sender;
+
+ private final boolean clearResourcePathCache;
+
+ public Invalidation(CDOCommitInfo commitInfo, InternalCDOTransaction sender, boolean clearResourcePathCache)
+ {
+ this.commitInfo = commitInfo;
+ this.sender = sender;
+ this.clearResourcePathCache = clearResourcePathCache;
+ }
+
+ public long getTimeStamp()
+ {
+ return commitInfo.getTimeStamp();
+ }
+
+ public long getPreviousTimeStamp()
+ {
+ return commitInfo.getPreviousTimeStamp();
+ }
+
+ public int compareTo(Invalidation o)
+ {
+ return CDOCommonUtil.compareTimeStamps(getTimeStamp(), o.getTimeStamp());
+ }
+
+ @Override
+ public String toString()
+ {
+ return Long.toString(commitInfo.getTimeStamp() % 10000);
+ }
+
+ public void run()
+ {
+ long timeStamp = commitInfo.getTimeStamp();
+
+ if (Invalidator.DEBUG)
+ {
+ IOUtil.OUT().println(
+ CDOSessionImpl.this + " [" + getLastUpdateTime() % 10000 + "] " + timeStamp % 10000 + " INVALIDATE");
+ }
+
+ try
+ {
+ Map<CDOID, InternalCDORevision> oldRevisions = null;
+ boolean success = commitInfo.getBranch() != null;
+ if (success)
+ {
+ oldRevisions = reviseRevisions(commitInfo);
+ }
+
+ if (options.isPassiveUpdateEnabled()/* || sender != null */)
+ {
+ setLastUpdateTime(timeStamp);
+ }
+
+ if (success)
+ {
+ CDOSessionImpl.this.fireEvent(new InvalidationEvent(sender, commitInfo));
+ commitInfoManager.notifyCommitInfoHandlers(commitInfo);
+ }
+
+ for (InternalCDOView view : getViews())
+ {
+ invalidateView(commitInfo, view, sender, oldRevisions, clearResourcePathCache);
+ }
+ }
+ catch (RuntimeException ex)
+ {
+ if (isActive())
+ {
+ throw ex;
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(Messages.getString("CDOSessionImpl.2")); //$NON-NLS-1$
+ }
+ }
+ finally
+ {
+ // setLastUpdateTimeStamp() is not synchronized with the Invalidator.
+ // Give the Invalidator another chance to schedule Invalidations.
+ invalidator.scheduleInvalidations();
+ }
+ }
+
+ private void invalidateView(CDOCommitInfo commitInfo, InternalCDOView view, InternalCDOTransaction sender,
+ Map<CDOID, InternalCDORevision> oldRevisions, boolean clearResourcePathCache)
+ {
+ try
+ {
+ long lastUpdateTime = commitInfo.getTimeStamp();
+ if (view == sender)
+ {
+ // The committing view (sender) is already valid, just the timestamp must be set "in sequence".
+ // Setting the sender's timestamp synchronously can lead to deadlock
+ view.invalidate(null, lastUpdateTime, null, null, null, true, false);
+ }
+ else
+ {
+ CDOBranch branch = commitInfo.getBranch();
+ List<CDORevisionKey> allChangedObjects = commitInfo.getChangedObjects();
+ List<CDOIDAndVersion> allDetachedObjects = commitInfo.getDetachedObjects();
+
+ view.invalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions, true,
+ clearResourcePathCache);
+ }
+ }
+ catch (RuntimeException ex)
+ {
+ if (view.isActive())
+ {
+ OM.LOG.error(ex);
+ }
+ else
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(Messages.getString("CDOSessionImpl.1")); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
private final class InvalidationEvent extends Event implements CDOSessionInvalidationEvent
{
private static final long serialVersionUID = 1L;
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
index 21d9f1a5f2..7fb9f44ac1 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
@@ -112,6 +112,7 @@ import org.eclipse.emf.internal.cdo.object.CDONotificationBuilder;
import org.eclipse.emf.internal.cdo.object.CDOObjectMerger;
import org.eclipse.emf.internal.cdo.object.CDOObjectWrapper;
import org.eclipse.emf.internal.cdo.query.CDOQueryImpl;
+import org.eclipse.emf.internal.cdo.session.CDOSessionImpl;
import org.eclipse.emf.internal.cdo.util.CommitIntegrityCheck;
import org.eclipse.emf.internal.cdo.util.CompletePackageClosure;
import org.eclipse.emf.internal.cdo.util.IPackageClosure;
@@ -1169,11 +1170,32 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return new CDOCommitContextImpl(this);
}
+ public/* synchronized */CDOCommitInfo commit() throws CommitException
+ {
+ return commit(null);
+ }
+
/**
* @since 2.0
*/
- public synchronized CDOCommitInfo commit(IProgressMonitor progressMonitor) throws CommitException
+ public/* synchronized */CDOCommitInfo commit(IProgressMonitor progressMonitor) throws CommitException
+ {
+ CDOCommitInfo info = commitSynced(progressMonitor);
+ if (info != null)
+ {
+ long timeStamp = info.getTimeStamp();
+ waitForUpdate(timeStamp, 10000);
+ }
+
+ return info;
+ }
+
+ private synchronized CDOCommitInfo commitSynced(IProgressMonitor progressMonitor) throws DanglingIntegrityException,
+ CommitException
{
+ Object token = null;
+ InternalCDOSession session = getSession();
+
try
{
checkActive();
@@ -1182,6 +1204,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
throw new LocalCommitConflictException(Messages.getString("CDOTransactionImpl.2")); //$NON-NLS-1$
}
+ if (session instanceof CDOSessionImpl)
+ {
+ token = ((CDOSessionImpl)session).startLocalCommit();
+ }
+
if (progressMonitor == null)
{
progressMonitor = new NullProgressMonitor();
@@ -1210,15 +1237,15 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
finally
{
+ if (session instanceof CDOSessionImpl)
+ {
+ ((CDOSessionImpl)session).endLocalCommit(token);
+ }
+
clearResourcePathCacheIfNecessary(null);
}
}
- public synchronized CDOCommitInfo commit() throws CommitException
- {
- return commit(null);
- }
-
/**
* @since 2.0
*/
@@ -3013,7 +3040,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
getAdapterManager().committedTransaction(transaction, this);
cleanUp(this);
- Map<CDOID, CDOID> idMappings = result.getIDMappings();
+
IListener[] listeners = getListeners();
if (listeners != null)
{
@@ -3022,6 +3049,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
fireViewTargetChangedEvent(oldBranch.getHead(), listeners);
}
+ Map<CDOID, CDOID> idMappings = result.getIDMappings();
fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.COMMITTED, idMappings), listeners);
}

Back to the top