Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2013-08-06 01:35:56 -0400
committerEike Stepper2013-08-06 01:56:35 -0400
commitec62f152d7309f888d2c2cea96181f5b60480b20 (patch)
treef8669dd9cb5ba9bca1eb0e839c49e0a67ed5b7f2
parent4f29ce12ff912157d32dd166f3a6e8aeac71d2a9 (diff)
downloadcdo-ec62f152d7309f888d2c2cea96181f5b60480b20.tar.gz
cdo-ec62f152d7309f888d2c2cea96181f5b60480b20.tar.xz
cdo-ec62f152d7309f888d2c2cea96181f5b60480b20.zip
[411939] CDOSessionImpl can "freeze" during invalidation reordering
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/internal/server/TransactionCommitContext.java26
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java25
-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.db/META-INF/MANIFEST.MF16
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.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_349804_Test.java51
-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/bugzilla/Bugzilla_411927_Test.java256
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java4
-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
17 files changed, 775 insertions, 382 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/internal/server/TransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
index 6dbe4b310f..c7ac0db18c 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
@@ -78,6 +78,7 @@ import org.eclipse.net4j.util.io.ExtendedDataInputStream;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.Monitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
@@ -101,6 +102,8 @@ import java.util.Set;
*/
public class TransactionCommitContext implements InternalCommitContext
{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSACTION, TransactionCommitContext.class);
+
private static final InternalCDORevision DETACHED = new StubCDORevision(null);
private final InternalTransaction transaction;
@@ -664,7 +667,11 @@ public class TransactionCommitContext implements InternalCommitContext
{
try
{
- OM.LOG.error(ex);
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(ex);
+ }
+
String storeClass = repository.getStore().getClass().getSimpleName();
rollback("Rollback in " + storeClass + ": " + StringUtil.formatException(ex)); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -677,7 +684,10 @@ public class TransactionCommitContext implements InternalCommitContext
try
{
- OM.LOG.error(ex1);
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(ex1);
+ }
}
catch (Exception ignore)
{
@@ -741,10 +751,14 @@ public class TransactionCommitContext implements InternalCommitContext
try
{
- InternalSession sender = transaction.getSession();
- CDOCommitInfo commitInfo = success ? createCommitInfo() : createFailureCommitInfo();
+ // Send notifications (in particular FailureCommitInfos) only if timeStamp had been allocated
+ if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ InternalSession sender = transaction.getSession();
+ CDOCommitInfo commitInfo = success ? createCommitInfo() : createFailureCommitInfo();
- repository.sendCommitNotification(sender, commitInfo, clearResourcePathCache);
+ repository.sendCommitNotification(sender, commitInfo, clearResourcePathCache);
+ }
}
catch (Exception ex)
{
@@ -1456,7 +1470,7 @@ public class TransactionCommitContext implements InternalCommitContext
/**
* @author Eike Stepper
*/
- private static final class RollbackException extends RuntimeException
+ protected static final class RollbackException extends RuntimeException
{
private static final long serialVersionUID = 1L;
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
index 9d5c13f363..4f3ffc4064 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
@@ -366,6 +366,8 @@ public abstract class SynchronizableRepository extends Repository.Default implem
{
try
{
+ long previousCommitTime = getLastCommitTimeStamp();
+
int fromBranchID = lastReplicatedBranchID + 1;
int toBranchID = in.readInt();
long fromCommitTime = lastReplicatedCommitTime + 1L;
@@ -377,7 +379,7 @@ public abstract class SynchronizableRepository extends Repository.Default implem
replicateRawReviseRevisions();
replicateRawReloadLocks();
- replicateRawNotifyClients(lastReplicatedCommitTime, toCommitTime);
+ replicateRawNotifyClients(lastReplicatedCommitTime, toCommitTime, previousCommitTime);
setLastReplicatedBranchID(toBranchID);
setLastReplicatedCommitTime(toCommitTime);
@@ -422,7 +424,7 @@ public abstract class SynchronizableRepository extends Repository.Default implem
getLockingManager().reloadLocks();
}
- private void replicateRawNotifyClients(long fromCommitTime, long toCommitTime)
+ private void replicateRawNotifyClients(long fromCommitTime, long toCommitTime, long previousCommitTime)
{
InternalCDOCommitInfoManager manager = getCommitInfoManager();
InternalSessionManager sessionManager = getSessionManager();
@@ -447,7 +449,7 @@ public abstract class SynchronizableRepository extends Repository.Default implem
CDOCommitData data = CDOCommitInfoUtil.createCommitData(newPackages, newObjects, changedObjects, detachedObjects);
String comment = "<replicate raw commits>"; //$NON-NLS-1$
- CDOCommitInfo commitInfo = manager.createCommitInfo(branch, toCommitTime, fromCommitTime, SYSTEM_USER_ID,
+ CDOCommitInfo commitInfo = manager.createCommitInfo(branch, toCommitTime, previousCommitTime, SYSTEM_USER_ID,
comment, data);
sessionManager.sendCommitNotification(replicatorSession, commitInfo, true);
}
@@ -909,6 +911,8 @@ public abstract class SynchronizableRepository extends Repository.Default implem
{
private static final int ARTIFICIAL_VIEW_ID = 0;
+ private CommitTransactionResult result;
+
public WriteThroughCommitContext(InternalTransaction transaction)
{
super(transaction);
@@ -1024,7 +1028,7 @@ public abstract class SynchronizableRepository extends Repository.Default implem
// Delegate commit to the master
CDOSessionProtocol sessionProtocol = getSynchronizer().getRemoteSession().getSessionProtocol();
- CommitTransactionResult result = sessionProtocol.commitDelegation(ctx, monitor);
+ result = sessionProtocol.commitDelegation(ctx, monitor);
// Stop if commit to master failed
String rollbackMessage = result.getRollbackMessage();
@@ -1034,8 +1038,7 @@ public abstract class SynchronizableRepository extends Repository.Default implem
}
// Prepare data needed for commit result and commit notifications
- long timeStamp = result.getTimeStamp();
- setTimeStamp(timeStamp);
+ long timeStamp = result.getTimeStamp(); // result is set to null later!
addIDMappings(result.getIDMappings());
applyIDMappings(new Monitor());
@@ -1064,10 +1067,14 @@ public abstract class SynchronizableRepository extends Repository.Default implem
@Override
protected long[] createTimeStamp(OMMonitor monitor)
{
- // Already set after commit to the master.
- // Do not call getTimeStamp() of the enclosing Repo class!!!
+ long timeStamp = result.getTimeStamp();
+ long previousTimeStamp = result.getPreviousTimeStamp();
+ result = null;
+
InternalRepository repository = getTransaction().getSession().getManager().getRepository();
- return repository.forceCommitTimeStamp(WriteThroughCommitContext.this.getTimeStamp(), monitor);
+ repository.forceCommitTimeStamp(timeStamp, monitor);
+
+ return new long[] { timeStamp, previousTimeStamp };
}
@Override
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.db/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.tests.db/META-INF/MANIFEST.MF
index 24ee731456..10b0c034b1 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.tests.db/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.emf.cdo.tests.db;singleton:=true
-Bundle-Version: 4.0.200.qualifier
+Bundle-Version: 4.0.201.qualifier
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -24,10 +24,10 @@ Import-Package: com.mysql.jdbc.jdbc2.optional;version="[5.0.0,6.0.0)",
org.hsqldb.jdbc;version="[2.0.0,3.0.0)",
org.postgresql.ds;version="[9.0.0,10.0.0)",
org.postgresql.ds.common;version="[9.0.0,10.0.0)"
-Export-Package: org.eclipse.emf.cdo.tests.db;version="4.0.200";x-friends:="org.eclipse.emf.cdo.tests.all",
- org.eclipse.emf.cdo.tests.db.bundle;version="4.0.200";x-internal:=true,
- org.eclipse.emf.cdo.tests.db.capabilities;version="4.0.200";x-friends:="org.eclipse.emf.cdo.tests.all",
- org.eclipse.emf.cdo.tests.db.offline;version="4.0.200";x-friends:="org.eclipse.emf.cdo.tests.all",
- org.eclipse.emf.cdo.tests.db.performance;version="4.0.200";x-friends:="org.eclipse.emf.cdo.tests.all",
- org.eclipse.emf.cdo.tests.db.revisioncache;version="4.0.200";x-friends:="org.eclipse.emf.cdo.tests.all",
- org.eclipse.emf.cdo.tests.db.verifier;version="4.0.200";x-friends:="org.eclipse.emf.cdo.tests.all"
+Export-Package: org.eclipse.emf.cdo.tests.db;version="4.0.201";x-friends:="org.eclipse.emf.cdo.tests.all",
+ org.eclipse.emf.cdo.tests.db.bundle;version="4.0.201";x-internal:=true,
+ org.eclipse.emf.cdo.tests.db.capabilities;version="4.0.201";x-friends:="org.eclipse.emf.cdo.tests.all",
+ org.eclipse.emf.cdo.tests.db.offline;version="4.0.201";x-friends:="org.eclipse.emf.cdo.tests.all",
+ org.eclipse.emf.cdo.tests.db.performance;version="4.0.201";x-friends:="org.eclipse.emf.cdo.tests.all",
+ org.eclipse.emf.cdo.tests.db.revisioncache;version="4.0.201";x-friends:="org.eclipse.emf.cdo.tests.all",
+ org.eclipse.emf.cdo.tests.db.verifier;version="4.0.201";x-friends:="org.eclipse.emf.cdo.tests.all"
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java
index 46ed8313f2..cf30e97a63 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java
@@ -65,13 +65,13 @@ public class H2Config extends DBConfig
if (defaultDataSource == null)
{
defaultDataSource = new JdbcDataSource();
- defaultDataSource.setURL("jdbc:h2:" + reusableFolder.getAbsolutePath() + "/h2test");
+ defaultDataSource.setURL("jdbc:h2:" + reusableFolder.getAbsolutePath() + "/h2test;LOCK_TIMEOUT=10000");
}
H2Adapter.createSchema(defaultDataSource, repoName, !isRestarting());
JdbcDataSource dataSource = new JdbcDataSource();
- dataSource.setURL("jdbc:h2:" + reusableFolder.getAbsolutePath() + "/h2test;SCHEMA=" + repoName);
+ dataSource.setURL("jdbc:h2:" + reusableFolder.getAbsolutePath() + "/h2test;LOCK_TIMEOUT=10000;SCHEMA=" + repoName);
return dataSource;
}
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_349804_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_349804_Test.java
index a0f8caed41..f929987779 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_349804_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_349804_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:
* Eike Stepper - initial API and implementation
*/
@@ -17,6 +17,7 @@ import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
import org.eclipse.emf.cdo.server.ITransaction;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
@@ -31,39 +32,52 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
+ * Bug 349804: Session is not invalidated after commit.
+ *
* @author Egidijus Vaisnora
*/
public class Bugzilla_349804_Test extends AbstractCDOTest
{
public void testInvalidation() throws CommitException, InterruptedException
{
+ disableConsole();
+ long timeStamp;
+
{
+ InternalRepository repository = getRepository();
+
CDOSession session = openSession();
- CDOTransaction transaction1 = session.openTransaction();
+ CDOTransaction transaction = session.openTransaction();
- transaction1.createResource(getResourcePath("test"));
- transaction1.commit();
+ transaction.createResource(getResourcePath("test"));
+ timeStamp = transaction.commit().getTimeStamp();
Failure handler = new Failure();
- getRepository().addHandler(handler);
- CDOTransaction failureTransaction = session.openTransaction();
- failureTransaction.createResource(getResourcePath("fail"));
+ repository.addHandler(handler);
try
{
// Creating failure commit. It will change last update time on server TimeStampAuthority
- failureTransaction.commit();
+ transaction.createResource(getResourcePath("fail"));
+ transaction.commit();
fail("CommitException expected");
}
catch (CommitException expected)
{
+ // SUCCESS
+ }
+ finally
+ {
+ repository.removeHandler(handler);
+ session.close();
}
- getRepository().removeHandler(handler);
- session.close();
+ assertNotSame(timeStamp, repository.getLastCommitTimeStamp());
}
CDOSession session = openSession();
+ assertEquals(getRepository().getLastCommitTimeStamp(), session.getLastUpdateTime());
+
CDOTransaction transaction = session.openTransaction();
final CountDownLatch invalidationLatch = new CountDownLatch(1);
@@ -85,7 +99,7 @@ public class Bugzilla_349804_Test extends AbstractCDOTest
// Invalidation shall fail, because it will use lastUpdateTime from TimeStampAuthority for commit result
transaction.commit();
- invalidationLatch.await(500, TimeUnit.MILLISECONDS);
+ invalidationLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
assertEquals("Invalidation was not delivered", 0, invalidationLatch.getCount());
}
@@ -98,12 +112,12 @@ public class Bugzilla_349804_Test extends AbstractCDOTest
transaction1.createResource(getResourcePath("test"));
transaction1.commit();
- Failure handler = new Failure();
- getRepository().addHandler(handler);
-
CDOTransaction failureTransaction = session.openTransaction();
failureTransaction.createResource(getResourcePath("fail"));
+ Failure handler = new Failure();
+ getRepository().addHandler(handler);
+
try
{
// Creating failure commit. It will change last update time on server TimeStampAuthority
@@ -112,10 +126,13 @@ public class Bugzilla_349804_Test extends AbstractCDOTest
}
catch (CommitException expected)
{
+ // SUCCESS
+ }
+ finally
+ {
+ getRepository().removeHandler(handler);
+ session.close();
}
-
- getRepository().removeHandler(handler);
- session.close();
}
CDOSession session = openSession();
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/bugzilla/Bugzilla_411927_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_411927_Test.java
new file mode 100644
index 0000000000..92d1ae79aa
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_411927_Test.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.internal.server.Repository;
+import org.eclipse.emf.cdo.internal.server.TransactionCommitContext;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesAfter;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
+import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig;
+import org.eclipse.emf.cdo.tests.model1.Category;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.CommitException;
+import org.eclipse.emf.cdo.util.ConcurrentAccessException;
+
+import java.util.Map;
+
+/**
+ * Bug 411927: CDOSessionImpl can "freeze" during invalidation reordering.
+ *
+ * @author Eike Stepper
+ */
+@CleanRepositoriesBefore
+@CleanRepositoriesAfter
+public class Bugzilla_411927_Test extends AbstractCDOTest
+{
+ private static final String RESOURCE_NAME = "res1";
+
+ private static final int CLIENTS = 20;
+
+ private static final int COMMITS_PER_CLIENT = 3;
+
+ private static final String BAD_COMMIT = "Bad Commit";
+
+ public void testWithoutFailure() throws Exception
+ {
+ executeTestWith(FailureTime.NEVER);
+ }
+
+ public void testWithFailureBeforeTimeStamp() throws Exception
+ {
+ executeTestWith(FailureTime.BEFORE_TIMESTAMP);
+ }
+
+ public void testWithFailureAfterTimeStamp() throws Exception
+ {
+ executeTestWith(FailureTime.AFTER_TIMESTAMP);
+ }
+
+ private void initRepository(final FailureTime failureTime)
+ {
+ Repository repository = new Repository.Default()
+ {
+ @Override
+ public InternalCommitContext createCommitContext(InternalTransaction transaction)
+ {
+ return new TransactionCommitContext(transaction)
+ {
+ @Override
+ protected void lockObjects() throws InterruptedException
+ {
+ if (failureTime == FailureTime.BEFORE_TIMESTAMP)
+ {
+ simulateProblem();
+ }
+
+ super.lockObjects();
+ }
+
+ @Override
+ protected void adjustForCommit()
+ {
+ if (failureTime == FailureTime.AFTER_TIMESTAMP)
+ {
+ simulateProblem();
+ }
+
+ super.adjustForCommit();
+ }
+
+ private void simulateProblem()
+ {
+ if (BAD_COMMIT.equals(getCommitComment()))
+ {
+ RuntimeException cause = new RuntimeException("SIMULATED PROBLEM");
+ throw new RollbackException(CDOProtocolConstants.ROLLBACK_REASON_OPTIMISTIC_LOCKING, cause);
+ }
+ }
+ };
+ }
+ };
+
+ repository.setName(IRepositoryConfig.REPOSITORY_NAME);
+
+ Map<String, String> props = getRepositoryProperties();
+ ((InternalRepository)repository).setProperties(props);
+
+ getTestProperties().put(RepositoryConfig.PROP_TEST_REPOSITORY, repository);
+ }
+
+ private void executeTestWith(FailureTime failureTime) throws ConcurrentAccessException, CommitException,
+ InterruptedException
+ {
+ disableConsole();
+ initRepository(failureTime);
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(getResourcePath(RESOURCE_NAME));
+ resource.getContents().add(getModel1Factory().createCompany());
+ transaction.commit();
+
+ Thread[] clients = new Thread[CLIENTS];
+ for (int id = 0; id < CLIENTS; id++)
+ {
+ if (failureTime == FailureTime.NEVER || id < CLIENTS - 1)
+ {
+ clients[id] = new GoodClient(id);
+ }
+ else
+ {
+ clients[id] = new BadClient(id);
+ }
+ }
+
+ for (int id = 0; id < CLIENTS; id++)
+ {
+ clients[id].start();
+ }
+
+ for (int id = 0; id < CLIENTS; id++)
+ {
+ clients[id].join();
+ }
+
+ assertEquals("Invalidation queue is blocked", true,
+ session.waitForUpdate(getRepository().getLastCommitTimeStamp(), DEFAULT_TIMEOUT));
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private enum FailureTime
+ {
+ NEVER, BEFORE_TIMESTAMP, AFTER_TIMESTAMP
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class GoodClient extends Thread
+ {
+ private final int id;
+
+ private Category category;
+
+ public GoodClient(int id) throws ConcurrentAccessException, CommitException
+ {
+ super("GoodClient-" + id);
+ this.id = id;
+ setDaemon(true);
+
+ category = getModel1Factory().createCategory();
+ category.setName(GoodClient.this.getName());
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.getResource(getResourcePath(RESOURCE_NAME));
+ Company company = (Company)resource.getContents().get(0);
+
+ company.getCategories().add(category);
+ transaction.commit();
+ }
+
+ @Override
+ public void run()
+ {
+ CDOTransaction transaction = (CDOTransaction)CDOUtil.getCDOObject(category).cdoView();
+ int objectsPerCommit = 10 * (CLIENTS - id);
+
+ for (int commit = 0; commit < COMMITS_PER_CLIENT; commit++)
+ {
+ for (int object = 0; object < objectsPerCommit; object++)
+ {
+ category.getProducts().add(getModel1Factory().createProduct1());
+ }
+
+ try
+ {
+ transaction.commit();
+ }
+ catch (CommitException ex)
+ {
+ ex.printStackTrace();
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class BadClient extends Thread
+ {
+ private Company company;
+
+ public BadClient(int id) throws ConcurrentAccessException, CommitException
+ {
+ super("BadClient-" + id);
+ setDaemon(true);
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.getResource(getResourcePath(RESOURCE_NAME));
+ company = (Company)resource.getContents().get(0);
+ }
+
+ @Override
+ public void run()
+ {
+ CDOTransaction transaction = (CDOTransaction)CDOUtil.getCDOObject(company).cdoView();
+ for (int commit = 0; commit < 100 * COMMITS_PER_CLIENT; commit++)
+ {
+ company.setName("Company-" + commit); // Make the transaction dirty
+
+ try
+ {
+ transaction.setCommitComment(BAD_COMMIT);
+ transaction.commit();
+ }
+ catch (CommitException 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..dfb70f2e8f 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
@@ -667,7 +667,7 @@ public class OfflineTest extends AbstractSyncingTest
InternalRepository clone = getRepository();
waitForOnline(clone);
- CDOSession session = openSession();
+ CDOSession session = openSession(); // Session2 [repo1]
session.options().setPassiveUpdateMode(PassiveUpdateMode.ADDITIONS);
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/my/resource"));
@@ -686,7 +686,7 @@ public class OfflineTest extends AbstractSyncingTest
transaction.addListener(transactionListener);
{
- CDOSession masterSession = openSession("master");
+ CDOSession masterSession = openSession("master"); // Session3 [master]
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.getResource(getResourcePath("/my/resource"));
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..385ab88557 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
{
+ InternalCDOSession session = getSession();
+ Object token = null;
+
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