summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaspar De Groot2011-09-19 01:40:08 (EDT)
committerCaspar De Groot2011-09-19 01:40:08 (EDT)
commitede599acbecf7b5aaa3c5e5e581ba91811e685ca (patch)
tree65f834bfb3abd4726e2964207dd7af2f962b7d17
parent98f83cd84af008140603c042ef337ad6c9c2e97f (diff)
downloadcdo-ede599acbecf7b5aaa3c5e5e581ba91811e685ca.zip
cdo-ede599acbecf7b5aaa3c5e5e581ba91811e685ca.tar.gz
cdo-ede599acbecf7b5aaa3c5e5e581ba91811e685ca.tar.bz2
[356754] Raw replication of persistent locks
https://bugs.eclipse.org/bugs/show_bug.cgi?id=356754
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java22
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java26
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java49
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java48
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractSyncingTest.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockRawReplicationTest.java23
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockReplicationTest.java169
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java111
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java21
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java16
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java5
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java99
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java6
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java17
24 files changed, 488 insertions, 220 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java
index c0207b8..7e73384 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java
@@ -31,6 +31,12 @@ import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
public interface CDOLockChangeInfo extends CDOBranchPoint
{
/**
+ * @return <code>true</code> if this instance signals that all {@link CDOLockState lockstates} must be invalidated,
+ * <code>false</code> otherwise
+ */
+ public boolean isInvalidateAll();
+
+ /**
* @return The branch at which the lock changes took place, same as <code>getView().getBranch()</code>.
*/
public CDOBranch getBranch();
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java
index fadcbd9..0f22468 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java
@@ -18,10 +18,10 @@ import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
+import org.eclipse.emf.cdo.internal.common.lock.CDOLockAreaImpl;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockChangeInfoImpl;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockOwnerImpl;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockStateImpl;
-import org.eclipse.emf.cdo.internal.common.lock.CDOLockAreaImpl;
import org.eclipse.emf.cdo.spi.common.lock.InternalCDOLockState;
import org.eclipse.net4j.util.CheckUtil;
@@ -72,7 +72,7 @@ public final class CDOLockUtil
sessionID = session.getSessionID();
viewID = view.getViewID();
}
-
+
CDOLockOwner owner = new CDOLockOwnerImpl(sessionID, viewID, durableLockingID, isDurableView);
cdoLockState.addReadLockOwner(owner);
}
@@ -104,7 +104,7 @@ public final class CDOLockUtil
int viewID = view.getViewID();
return new CDOLockOwnerImpl(sessionID, viewID, durableLockingID, false);
}
-
+
CheckUtil.checkNull(durableLockingID, "durableLockingID");
return new CDOLockOwnerImpl(0, 0, durableLockingID, true); // TODO (CD) Symbolic constants?
}
@@ -115,6 +115,11 @@ public final class CDOLockUtil
return new CDOLockChangeInfoImpl(branch.getPoint(timestamp), lockOwner, cdoLockStates, op, lockType);
}
+ public static CDOLockChangeInfo createLockChangeInfo()
+ {
+ return new CDOLockChangeInfoImpl();
+ }
+
public static CDOLockChangeInfo createLockChangeInfo(long timestamp, CDOCommonView view, CDOBranch viewedBranch,
Operation op, LockType lockType, CDOLockState[] cdoLockStates)
{
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java
index 46e883e..47379cc 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java
@@ -33,6 +33,8 @@ public class CDOLockChangeInfoImpl implements CDOLockChangeInfo
private final LockType lockType;
+ private final boolean isInvalidateAll;
+
public CDOLockChangeInfoImpl(CDOBranchPoint branchPoint, CDOLockOwner lockOwner, CDOLockState[] lockStates,
Operation operation, LockType lockType)
{
@@ -41,16 +43,27 @@ public class CDOLockChangeInfoImpl implements CDOLockChangeInfo
this.lockStates = lockStates;
this.operation = operation;
this.lockType = lockType;
+ isInvalidateAll = false;
+ }
+
+ public CDOLockChangeInfoImpl()
+ {
+ branchPoint = null;
+ lockOwner = null;
+ lockStates = null;
+ operation = null;
+ lockType = null;
+ isInvalidateAll = true;
}
public CDOBranch getBranch()
{
- return branchPoint.getBranch();
+ return branchPoint == null ? null : branchPoint.getBranch();
}
public long getTimeStamp()
{
- return branchPoint.getTimeStamp();
+ return branchPoint == null ? CDOBranchPoint.UNSPECIFIED_DATE : branchPoint.getTimeStamp();
}
public CDOLockOwner getLockOwner()
@@ -72,4 +85,9 @@ public class CDOLockChangeInfoImpl implements CDOLockChangeInfo
{
return lockType;
}
+
+ public boolean isInvalidateAll()
+ {
+ return isInvalidateAll;
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
index 79bfddb..af4a9a4 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
@@ -30,6 +30,7 @@ import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
@@ -270,6 +271,12 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
public CDOLockChangeInfo readCDOLockChangeInfo() throws IOException
{
+ boolean isInvalidateAll = readBoolean();
+ if (isInvalidateAll)
+ {
+ return CDOLockUtil.createLockChangeInfo();
+ }
+
CDOBranchPoint branchPoint = readCDOBranchPoint();
CDOLockOwner lockOwner = readCDOLockOwner();
Operation operation = readEnum(Operation.class);
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java
index b36a7ca..df2a2a7 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java
@@ -227,16 +227,24 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im
public void writeCDOLockChangeInfo(CDOLockChangeInfo lockChangeInfo) throws IOException
{
- writeCDOBranchPoint(lockChangeInfo);
- writeCDOLockOwner(lockChangeInfo.getLockOwner());
- writeEnum(lockChangeInfo.getOperation());
- writeCDOLockType(lockChangeInfo.getLockType());
-
- CDOLockState[] lockStates = lockChangeInfo.getLockStates();
- writeInt(lockStates.length);
- for (CDOLockState lockState : lockStates)
+ if (lockChangeInfo.isInvalidateAll())
+ {
+ writeBoolean(true);
+ }
+ else
{
- writeCDOLockState(lockState);
+ writeBoolean(false);
+ writeCDOBranchPoint(lockChangeInfo);
+ writeCDOLockOwner(lockChangeInfo.getLockOwner());
+ writeEnum(lockChangeInfo.getOperation());
+ writeCDOLockType(lockChangeInfo.getLockType());
+
+ CDOLockState[] lockStates = lockChangeInfo.getLockStates();
+ writeInt(lockStates.length);
+ for (CDOLockState lockState : lockStates)
+ {
+ writeCDOLockState(lockState);
+ }
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
index 7aa0813..9745ba6 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
@@ -1102,6 +1102,9 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
where = " WHERE " + CDODBSchema.COMMIT_INFOS_TIMESTAMP + " BETWEEN " + fromCommitTime + " AND " + toCommitTime;
DBUtil.serializeTable(out, connection, CDODBSchema.COMMIT_INFOS, null, where);
+ DurableLockingManager durableLockingManager = store.getDurableLockingManager();
+ durableLockingManager.rawExport(connection, out, fromCommitTime, toCommitTime);
+
IIDHandler idHandler = store.getIDHandler();
idHandler.rawExport(connection, out, fromCommitTime, toCommitTime);
@@ -1116,14 +1119,15 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
OMMonitor monitor) throws IOException
{
DBStore store = getStore();
+ IIDHandler idHandler = store.getIDHandler();
if (store.getRepository().getIDGenerationLocation() == IDGenerationLocation.STORE)
{
- store.getIDHandler().setLastObjectID(in.readCDOID()); // See bug 325097
+ idHandler.setLastObjectID(in.readCDOID()); // See bug 325097
}
IMappingStrategy mappingStrategy = store.getMappingStrategy();
int size = mappingStrategy.getClassMappings().size();
- int commitWork = 4;
+ int commitWork = 5;
monitor.begin(commitWork + size + commitWork);
Collection<InternalCDOPackageUnit> packageUnits = new HashSet<InternalCDOPackageUnit>();
@@ -1132,9 +1136,16 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
{
DBUtil.deserializeTable(in, connection, CDODBSchema.BRANCHES, monitor.fork());
DBUtil.deserializeTable(in, connection, CDODBSchema.COMMIT_INFOS, monitor.fork());
- store.getIDHandler().rawImport(connection, in, fromCommitTime, toCommitTime, monitor.fork());
+
+ DurableLockingManager durableLockingManager = store.getDurableLockingManager();
+ durableLockingManager.rawImport(connection, in, fromCommitTime, toCommitTime, monitor.fork());
+
+ idHandler.rawImport(connection, in, fromCommitTime, toCommitTime, monitor.fork());
+
rawImportPackageUnits(in, fromCommitTime, toCommitTime, packageUnits, monitor.fork());
+
mappingStrategy.rawImport(this, in, fromCommitTime, toCommitTime, monitor.fork(size));
+
rawCommit(commitWork, monitor);
}
catch (RuntimeException ex)
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
index a0b30c2..3fb707d 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
@@ -18,6 +18,8 @@ import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea.Handler;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaAlreadyExistsException;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaNotFoundException;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
+import org.eclipse.emf.cdo.common.protocol.CDODataInput;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
@@ -34,7 +36,9 @@ import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -86,6 +90,8 @@ public class DurableLockingManager extends Lifecycle
private String sqlDeleteLockArea;
+ private String sqlDeleteLockAreas;
+
private String sqlSelectLocks;
private String sqlSelectLock;
@@ -484,6 +490,18 @@ public class DurableLockingManager extends Lifecycle
sqlDeleteLockArea = builder.toString();
builder = new StringBuilder();
+ builder.append("DELETE FROM ");
+ builder.append(lockAreas);
+ builder.append(" a WHERE EXISTS (SELECT * FROM ");
+ builder.append(locks);
+ builder.append(" l WHERE l.");
+ builder.append(locksArea);
+ builder.append("=a.");
+ builder.append(lockAreasID);
+ builder.append(")");
+ sqlDeleteLockAreas = builder.toString();
+
+ builder = new StringBuilder();
builder.append("SELECT "); //$NON-NLS-1$
builder.append(locksObject);
builder.append(","); //$NON-NLS-1$
@@ -684,4 +702,35 @@ public class DurableLockingManager extends Lifecycle
statementCache.releasePreparedStatement(stmtSelect);
}
}
+
+ public void rawExport(Connection connection, CDODataOutput out, long fromCommitTime, long toCommitTime)
+ throws IOException
+ {
+ DBUtil.serializeTable(out, connection, lockAreas, null, null);
+ DBUtil.serializeTable(out, connection, locks, null, null);
+ }
+
+ public void rawImport(Connection connection, CDODataInput in, long fromCommitTime, long toCommitTime,
+ OMMonitor monitor) throws IOException
+ {
+ monitor.begin(4);
+
+ try
+ {
+ // Delete all non-empty lock areas
+ DBUtil.update(connection, sqlDeleteLockAreas);
+ monitor.worked();
+
+ DBUtil.deserializeTable(in, connection, lockAreas, monitor.fork());
+
+ DBUtil.clearTable(connection, locks);
+ monitor.worked();
+
+ DBUtil.deserializeTable(in, connection, locks, monitor.fork());
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
index 8da822d..86af310 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
@@ -352,7 +352,7 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
protected void doActivate() throws Exception
{
super.doActivate();
- loadDurableLocks();
+ loadLocks();
getRepository().getSessionManager().addListener(sessionManagerListener);
}
@@ -391,7 +391,13 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
throw new IllegalStateException("Store does not implement " + DurableLocking2.class.getSimpleName());
}
- private void loadDurableLocks()
+ public void reloadLocks()
+ {
+ DurableLockLoader handler = new DurableLockLoader();
+ getLockAreas(null, handler);
+ }
+
+ private void loadLocks()
{
InternalStore store = repository.getStore();
IStoreAccessor reader = null;
@@ -402,9 +408,7 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
if (reader instanceof DurableLocking)
{
StoreThreadLocal.setAccessor(reader);
-
- DurableLockLoader handler = new DurableLockLoader();
- getLockAreas(null, handler);
+ reloadLocks();
}
}
finally
@@ -578,10 +582,26 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
{
}
+ private IView getView(String lockAreaID)
+ {
+ IView view = openViews.get(lockAreaID);
+ if (view == null)
+ {
+ view = durableViews.get(lockAreaID);
+ }
+
+ return view;
+ }
+
public boolean handleLockArea(LockArea area)
{
String durableLockingID = area.getDurableLockingID();
- IView view = durableViews.get(durableLockingID);
+ IView view = getView(durableLockingID);
+ if (view != null)
+ {
+ unlock2(view);
+ }
+
if (view == null)
{
view = new DurableView(durableLockingID);
@@ -640,19 +660,10 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
}
}
}
+
return grade;
}
- private IView getView(String lockAreaID)
- {
- IView view = openViews.get(lockAreaID);
- if (view == null)
- {
- view = durableViews.get(lockAreaID);
- }
- return view;
- }
-
private LockArea getLockAreaNoEx(String durableLockingID)
{
try
@@ -683,11 +694,6 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
else
{
accessor.updateLockArea(lockArea);
- IView view = getView(durableLockingID);
- if (view != null)
- {
- unlock2(view);
- }
new DurableLockLoader().handleLockArea(lockArea);
}
}
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 c53e956..79bd4ca 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
@@ -16,6 +16,7 @@ package org.eclipse.emf.cdo.internal.server;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.CDOCommonSession;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
@@ -491,10 +492,14 @@ public class Session extends Container<IView> implements InternalSession
// only then do we send the lockChangeInfo.
for (InternalView view : getViews())
{
- if (view.options().isLockNotificationEnabled() && view.getBranch().equals(lockChangeInfo.getBranch()))
+ if (view.options().isLockNotificationEnabled())
{
- protocol.sendLockNotification(lockChangeInfo);
- break;
+ CDOBranch affectedBranch = lockChangeInfo.getBranch();
+ if (view.getBranch().equals(affectedBranch) || affectedBranch == null)
+ {
+ protocol.sendLockNotification(lockChangeInfo);
+ break;
+ }
}
}
}
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 ceb9b05..9933d18 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
@@ -24,6 +24,7 @@ import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
@@ -291,8 +292,8 @@ public abstract class SynchronizableRepository extends Repository.Default implem
// If we can't lock immediately, there's a conflict, which means we're in big
// trouble: somehow locks were obtained on the clone but not on the master. What to do?
// TODO (CD) Consider this problem further
- //
long timeout = 0;
+
super.lock(view, lockType, lockables, null, timeout);
}
else if (lockChangeInfo.getOperation() == Operation.UNLOCK)
@@ -317,7 +318,7 @@ public abstract class SynchronizableRepository extends Repository.Default implem
StoreThreadLocal.setSession(replicatorSession);
getLockManager().updateLockArea(area);
- // TODO (CD) getSessionManager().sendLockNotification(sender, lockChangeInfo);
+ getSessionManager().sendLockNotification(null, CDOLockUtil.createLockChangeInfo());
return true;
}
finally
@@ -340,6 +341,7 @@ public abstract class SynchronizableRepository extends Repository.Default implem
accessor.rawImport(in, fromBranchID, toBranchID, fromCommitTime, toCommitTime, monitor);
replicateRawReviseRevisions();
+ replicateRawReloadLocks();
replicateRawNotifyClients(lastReplicatedCommitTime, toCommitTime);
setLastReplicatedBranchID(toBranchID);
@@ -380,6 +382,11 @@ public abstract class SynchronizableRepository extends Repository.Default implem
}
}
+ private void replicateRawReloadLocks()
+ {
+ getLockManager().reloadLocks();
+ }
+
private void replicateRawNotifyClients(long fromCommitTime, long toCommitTime)
{
InternalCDOCommitInfoManager manager = getCommitInfoManager();
@@ -408,6 +415,9 @@ public abstract class SynchronizableRepository extends Repository.Default implem
comment, data);
sessionManager.sendCommitNotification(replicatorSession, commitInfo);
}
+
+ CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo();
+ sessionManager.sendLockNotification(replicatorSession, lockChangeInfo);
}
private Map<CDOBranch, TimeRange> replicateRawGetBranches(long fromCommitTime, long toCommitTime)
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java
index 45869dc..4c2ac99 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java
@@ -136,4 +136,9 @@ public interface InternalLockManager extends IRWOLockManager<Object, IView>, IDu
* @since 4.1
*/
public void setLockState(Object key, LockState<Object, IView> lockState);
+
+ /**
+ * @since 4.1
+ */
+ public void reloadLocks();
}
diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java
index 4cd2b61..f7bd71a 100644
--- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java
+++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBH2Offline.java
@@ -21,6 +21,8 @@ import org.eclipse.emf.cdo.tests.offline.Bugzilla_329014_Test;
import org.eclipse.emf.cdo.tests.offline.Bugzilla_351078_Test;
import org.eclipse.emf.cdo.tests.offline.FailoverTest;
import org.eclipse.emf.cdo.tests.offline.OfflineDelayedTest;
+import org.eclipse.emf.cdo.tests.offline.OfflineLockRawReplicationTest;
+import org.eclipse.emf.cdo.tests.offline.OfflineLockReplicationTest;
import org.eclipse.emf.cdo.tests.offline.OfflineLockingTest;
import org.eclipse.emf.cdo.tests.offline.OfflineRawTest;
import org.eclipse.emf.cdo.tests.offline.OfflineTest;
@@ -55,6 +57,8 @@ public class AllTestsDBH2Offline extends DBConfigs
testClasses.add(OfflineRawTest.class);
testClasses.add(OfflineDelayedTest.class);
testClasses.add(OfflineLockingTest.class);
+ testClasses.add(OfflineLockReplicationTest.class);
+ testClasses.add(OfflineLockRawReplicationTest.class);
testClasses.add(Bugzilla_329014_Test.class);
testClasses.add(Bugzilla_328352_Test.class);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractSyncingTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractSyncingTest.java
index a4d9fca..d2b6d92 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractSyncingTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractSyncingTest.java
@@ -245,4 +245,12 @@ public abstract class AbstractSyncingTest extends AbstractCDOTest
ConcurrencyUtil.sleep(SLEEP_MILLIS);
}
}
+
+ protected static CDOTransaction openTransaction(CDOSession session)
+ {
+ CDOTransaction tx = session.openTransaction();
+ tx.options().setLockNotificationEnabled(true);
+ tx.enableDurableLocking(true);
+ return tx;
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java
index cd92e90..7ad9814 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsMEMOffline.java
@@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.tests.config.IScenario;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
import org.eclipse.emf.cdo.tests.offline.FailoverTest;
import org.eclipse.emf.cdo.tests.offline.OfflineDelayed2Test;
+import org.eclipse.emf.cdo.tests.offline.OfflineLockReplicationTest;
import org.eclipse.emf.cdo.tests.offline.OfflineLockingTest;
import org.eclipse.emf.cdo.tests.offline.OfflineTest;
@@ -41,12 +42,14 @@ public class AllTestsMEMOffline extends AllConfigs
@Override
protected void initTestClasses(List<Class<? extends ConfigTest>> testClasses, IScenario scenario)
{
- // MEM does not support raw replication
- // testClasses.add(OfflineRawTest.class);
-
testClasses.add(OfflineLockingTest.class);
+ testClasses.add(OfflineLockReplicationTest.class);
testClasses.add(OfflineTest.class);
testClasses.add(OfflineDelayed2Test.class);
testClasses.add(FailoverTest.class);
+
+ // MEM does not support raw replication
+ // testClasses.add(OfflineRawTest.class);
+ // testClasses.add(OfflineLockRawReplicationTest.class);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java
index b6cc6f9..0764a1a 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java
@@ -117,10 +117,6 @@ public class OfflineDelayedTest extends AbstractSyncingTest
waitForOnline(clone);
}
- // public void testXXX() throws Exception
- // {
- // }
-
public void _testSyncWhileCommittingToMaster_NewPackage() throws Exception
{
TestListener listener = new TestListener();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockRawReplicationTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockRawReplicationTest.java
new file mode 100644
index 0000000..229fcf4
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockRawReplicationTest.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2004 - 2011 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:
+ * Caspar De Groot - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.offline;
+
+/**
+ * @author Caspar De Groot
+ */
+public class OfflineLockRawReplicationTest extends OfflineLockReplicationTest
+{
+ @Override
+ protected boolean isRawReplication()
+ {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockReplicationTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockReplicationTest.java
new file mode 100644
index 0000000..9af878a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockReplicationTest.java
@@ -0,0 +1,169 @@
+/**
+ * Copyright (c) 2004 - 2011 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:
+ * Caspar De Groot - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.offline;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.internal.server.syncing.OfflineClone;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.tests.AbstractSyncingTest;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.tests.util.TestListener2;
+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.view.CDOViewLocksChangedEvent;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * @author Caspar De Groot
+ */
+public class OfflineLockReplicationTest extends AbstractSyncingTest
+{
+ public void testCloneLocks_replicationToOtherClone_newSession() throws CommitException
+ {
+ testCloneLocks_replicationToOtherClone(false);
+ }
+
+ public void testCloneLocks_replicationToOtherClone_sameSession() throws CommitException
+ {
+ testCloneLocks_replicationToOtherClone(true);
+ }
+
+ private void testCloneLocks_replicationToOtherClone(boolean keepSession) throws CommitException
+ {
+ InternalRepository repo1 = getRepository("repo1");
+ assertEquals(true, repo1 instanceof OfflineClone);
+ InternalRepository repo2 = getRepository("repo2");
+ assertEquals(true, repo2 instanceof OfflineClone);
+
+ OfflineClone clone2 = (OfflineClone)repo2;
+
+ waitForOnline(getRepository("repo1"));
+ waitForOnline(getRepository("repo2"));
+
+ CDOSession clone1session = openSession("repo1");
+
+ // Store 3 objects in repo1
+ CDOTransaction tx1_sess1 = openTransaction(clone1session);
+ CDOResource resource_tx1_sess1 = tx1_sess1.createResource(getResourcePath("test"));
+ Company companyA = getModel1Factory().createCompany();
+ Company companyB = getModel1Factory().createCompany();
+ Company companyC = getModel1Factory().createCompany();
+ resource_tx1_sess1.getContents().add(companyA);
+ resource_tx1_sess1.getContents().add(companyB);
+ resource_tx1_sess1.getContents().add(companyC);
+ tx1_sess1.commit();
+
+ CDOTransaction tx1_sess2;
+ {
+ // Verify that they're visible in repo2
+ tx1_sess2 = openTransactionWithLockListener("repo2");
+ CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
+ assertEquals(3, resource_tx1_sess2.getContents().size());
+
+ if (!keepSession)
+ {
+ tx1_sess2.getSession().close();
+ tx1_sess2 = null;
+ }
+ }
+
+ clone2.goOffline();
+ waitForOffline(clone2);
+
+ // Lock the objects in repo1. Since repo1 is ONLINE, this will also lock them
+ // in the master.
+ CDOUtil.getCDOObject(companyA).cdoReadLock().lock();
+ CDOUtil.getCDOObject(companyB).cdoWriteLock().lock();
+ CDOUtil.getCDOObject(companyC).cdoWriteOption().lock();
+
+ clone2.goOnline();
+ waitForOnline(clone2);
+
+ {
+ // Verify that the locks are visible in repo2
+ if (!keepSession)
+ {
+ tx1_sess2 = openTransactionWithLockListener("repo2");
+ }
+ else
+ {
+ ((TestListener2)tx1_sess2.getListeners()[0]).waitFor(1);
+ }
+
+ CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
+ EList<EObject> contents = resource_tx1_sess2.getContents();
+ CDOObject companyA_in_sess2 = CDOUtil.getCDOObject(contents.get(0));
+ CDOObject companyB_in_sess2 = CDOUtil.getCDOObject(contents.get(1));
+ CDOObject companyC_in_sess2 = CDOUtil.getCDOObject(contents.get(2));
+
+ assertEquals(true, companyA_in_sess2.cdoReadLock().isLockedByOthers());
+ assertEquals(true, companyB_in_sess2.cdoWriteLock().isLockedByOthers());
+ assertEquals(true, companyC_in_sess2.cdoWriteOption().isLockedByOthers());
+
+ if (!keepSession)
+ {
+ tx1_sess2.getSession().close();
+ tx1_sess2 = null;
+ }
+ }
+
+ clone2.goOffline();
+ waitForOffline(clone2);
+
+ // Unlock the objects in repo1. Since repo1 is ONLINE, this will also lock them
+ // in the master.
+ CDOUtil.getCDOObject(companyA).cdoReadLock().unlock();
+ CDOUtil.getCDOObject(companyB).cdoWriteLock().unlock();
+ CDOUtil.getCDOObject(companyC).cdoWriteOption().unlock();
+
+ clone2.goOnline();
+ waitForOnline(clone2);
+
+ {
+ // Verify in repo2
+ if (!keepSession)
+ {
+ tx1_sess2 = openTransactionWithLockListener("repo2");
+ }
+ else
+ {
+ ((TestListener2)tx1_sess2.getListeners()[0]).waitFor(2);
+ }
+
+ CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
+ EList<EObject> contents = resource_tx1_sess2.getContents();
+ CDOObject companyA_in_sess2 = CDOUtil.getCDOObject(contents.get(0));
+ CDOObject companyB_in_sess2 = CDOUtil.getCDOObject(contents.get(1));
+ CDOObject companyC_in_sess2 = CDOUtil.getCDOObject(contents.get(2));
+
+ assertEquals(false, companyA_in_sess2.cdoReadLock().isLockedByOthers());
+ assertEquals(false, companyB_in_sess2.cdoWriteLock().isLockedByOthers());
+ assertEquals(false, companyC_in_sess2.cdoWriteOption().isLockedByOthers());
+
+ tx1_sess2.getSession().close();
+ }
+
+ clone1session.close();
+ }
+
+ private CDOTransaction openTransactionWithLockListener(String repoName)
+ {
+ CDOSession session = openSession(repoName);
+ CDOTransaction tx = openTransaction(session);
+ tx.addListener(new TestListener2(CDOViewLocksChangedEvent.class));
+ return tx;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
index 95312e7..9ef3f09 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
@@ -17,21 +17,16 @@ import org.eclipse.emf.cdo.internal.server.syncing.OfflineClone;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.tests.AbstractSyncingTest;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.util.TestListener2;
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.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EObject;
-
/**
* @author Caspar De Groot
*/
@@ -194,110 +189,4 @@ public class OfflineLockingTest extends AbstractSyncingTest
clone1Session.close();
clone2Session.close();
}
-
- public void testCloneLocks_replicationToOtherClone() throws CommitException
- {
- InternalRepository repo1 = getRepository("repo1");
- assertEquals(true, repo1 instanceof OfflineClone);
- InternalRepository repo2 = getRepository("repo2");
- assertEquals(true, repo2 instanceof OfflineClone);
-
- OfflineClone clone2 = (OfflineClone)repo2;
-
- waitForOnline(getRepository("repo1"));
- waitForOnline(getRepository("repo2"));
-
- CDOSession clone1session = openSession("repo1");
-
- // Store 3 objects in repo1
- CDOTransaction tx1_sess1 = openTransaction(clone1session);
- CDOResource resource_tx1_sess1 = tx1_sess1.createResource(getResourcePath("test"));
- Company companyA = getModel1Factory().createCompany();
- Company companyB = getModel1Factory().createCompany();
- Company companyC = getModel1Factory().createCompany();
- resource_tx1_sess1.getContents().add(companyA);
- resource_tx1_sess1.getContents().add(companyB);
- resource_tx1_sess1.getContents().add(companyC);
- tx1_sess1.commit();
-
- {
- // Verify that they're visible in repo2
- CDOSession clone2session = openSession("repo2");
- CDOTransaction tx1_sess2 = openTransaction(clone2session);
- CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
- assertEquals(3, resource_tx1_sess2.getContents().size());
- tx1_sess2.close();
- clone2session.close();
- }
-
- clone2.goOffline();
- waitForOffline(clone2);
-
- // Lock the objects in repo1. Since repo1 is ONLINE, this will also lock them
- // in the master.
- CDOUtil.getCDOObject(companyA).cdoReadLock().lock();
- CDOUtil.getCDOObject(companyB).cdoWriteLock().lock();
- CDOUtil.getCDOObject(companyC).cdoWriteOption().lock();
-
- clone2.goOnline();
- waitForOnline(clone2);
-
- {
- // Verify that the locks are visible in repo2
- CDOSession clone2session = openSession("repo2");
- CDOTransaction tx1_sess2 = openTransaction(clone2session);
- CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
- EList<EObject> contents = resource_tx1_sess2.getContents();
- CDOObject companyA_in_sess2 = CDOUtil.getCDOObject(contents.get(0));
- CDOObject companyB_in_sess2 = CDOUtil.getCDOObject(contents.get(1));
- CDOObject companyC_in_sess2 = CDOUtil.getCDOObject(contents.get(2));
-
- assertEquals(true, companyA_in_sess2.cdoReadLock().isLockedByOthers());
- assertEquals(true, companyB_in_sess2.cdoWriteLock().isLockedByOthers());
- assertEquals(true, companyC_in_sess2.cdoWriteOption().isLockedByOthers());
-
- tx1_sess2.close();
- clone2session.close();
- }
-
- clone2.goOffline();
- waitForOffline(clone2);
-
- // Unlock the objects in repo1. Since repo1 is ONLINE, this will also lock them
- // in the master.
- CDOUtil.getCDOObject(companyA).cdoReadLock().unlock();
- CDOUtil.getCDOObject(companyB).cdoWriteLock().unlock();
- CDOUtil.getCDOObject(companyC).cdoWriteOption().unlock();
-
- clone2.goOnline();
- waitForOnline(clone2);
-
- {
- // Verify in repo2
- CDOSession clone2session = openSession("repo2");
- CDOTransaction tx1_sess2 = openTransaction(clone2session);
- CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
- EList<EObject> contents = resource_tx1_sess2.getContents();
- CDOObject companyA_in_sess2 = CDOUtil.getCDOObject(contents.get(0));
- CDOObject companyB_in_sess2 = CDOUtil.getCDOObject(contents.get(1));
- CDOObject companyC_in_sess2 = CDOUtil.getCDOObject(contents.get(2));
-
- assertEquals(false, companyA_in_sess2.cdoReadLock().isLockedByOthers());
- assertEquals(false, companyB_in_sess2.cdoWriteLock().isLockedByOthers());
- assertEquals(false, companyC_in_sess2.cdoWriteOption().isLockedByOthers());
-
- tx1_sess2.close();
- clone2session.close();
- }
-
- clone1session.close();
- }
-
- private static CDOTransaction openTransaction(CDOSession session)
- {
- CDOTransaction tx = session.openTransaction();
- tx.options().setLockNotificationEnabled(true);
- tx.enableDurableLocking(true);
- return tx;
- }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
index 5c917bb..fe4b21d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
@@ -86,8 +86,6 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
private InternalCDORevision revision;
- private CDOLockState lockState;
-
/**
* CDO uses this list instead of eSettings for transient objects. EMF uses eSettings as cache. CDO deactivates the
* cache but EMF still used eSettings to store list wrappers. CDO needs another place to store the real list with the
@@ -225,25 +223,14 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
/**
* @since 4.1
*/
- public synchronized CDOLockState cdoLockState()
+ public CDOLockState cdoLockState()
{
- if (lockState == null)
+ if (!FSMUtil.isTransient(this) && !FSMUtil.isNew(this))
{
- if (!FSMUtil.isTransient(this) && !FSMUtil.isNew(this))
- {
- lockState = view.getLockStates(Collections.singletonList(id))[0];
- }
+ return view.getLockStates(Collections.singletonList(id))[0];
}
- return lockState;
- }
-
- /**
- * @since 4.1
- */
- public synchronized void cdoInternalSetLockState(CDOLockState lockState)
- {
- this.lockState = lockState;
+ return null;
}
public void cdoInternalSetID(CDOID id)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
index df07507..2aae1a4 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
@@ -97,8 +97,6 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper
protected InternalCDORevision revision;
- protected CDOLockState lockState;
-
/**
* It could happen that while <i>revisionToInstance()</i> is executed externally the <i>internalPostLoad()</i> method
* will be called. This happens for example if <i>internalPostInvalidate()</i> is called. The leads to another
@@ -127,20 +125,12 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper
public synchronized CDOLockState cdoLockState()
{
- if (lockState == null)
+ if (!FSMUtil.isTransient(this) && !FSMUtil.isNew(this))
{
- if (!FSMUtil.isTransient(this) && !FSMUtil.isNew(this))
- {
- lockState = view.getLockStates(Collections.singletonList(id))[0];
- }
+ return view.getLockStates(Collections.singletonList(id))[0];
}
- return lockState;
- }
-
- public synchronized void cdoInternalSetLockState(CDOLockState lockState)
- {
- this.lockState = lockState;
+ return null;
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java
index 0dedde5..260f296 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java
@@ -74,4 +74,9 @@ public class DefaultLocksChangedEvent extends Event implements CDOLockChangeInfo
{
return lockChangeInfo.getLockType();
}
+
+ public boolean isInvalidateAll()
+ {
+ return lockChangeInfo.isInvalidateAll();
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
index d2a462a..c261acb 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
@@ -103,6 +103,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.WeakHashMap;
/**
* @author Eike Stepper
@@ -129,6 +130,8 @@ public class CDOViewImpl extends AbstractCDOView
private QueueRunner invalidationRunner;
+ private Map<InternalCDOObject, CDOLockState> lockStates = new WeakHashMap<InternalCDOObject, CDOLockState>();
+
@ExcludeFromDump
private InvalidationRunnerLock invalidationRunnerLock = new InvalidationRunnerLock();
@@ -339,7 +342,7 @@ public class CDOViewImpl extends AbstractCDOView
InternalCDOObject obj = getObject(id, false);
if (obj != null)
{
- obj.cdoInternalSetLockState(lockState);
+ lockStates.put(obj, lockState);
}
}
}
@@ -363,29 +366,51 @@ public class CDOViewImpl extends AbstractCDOView
public void handleLockNotification(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
{
- if (!options().isLockNotificationEnabled())
- {
- return;
- }
+ CDOLockChangeInfo event = null;
- // If lockChangeInfo pertains to a different view, do nothing.
- if (!lockChangeInfo.getBranch().equals(getBranch()))
+ try
{
- return;
- }
+ synchronized (this)
+ {
+ if (!options().isLockNotificationEnabled())
+ {
+ return;
+ }
+
+ if (lockChangeInfo.isInvalidateAll())
+ {
+ lockStates.clear();
+ event = lockChangeInfo;
+ return;
+ }
+
+ // If lockChangeInfo pertains to a different view, do nothing.
+ if (!lockChangeInfo.getBranch().equals(getBranch()))
+ {
+ return;
+ }
- // If lockChangeInfo represents lock changes authored by this view itself, do nothing.
- CDOLockOwner thisView = CDOLockUtil.createLockOwner(this);
- if (lockChangeInfo.getLockOwner().equals(thisView))
+ // If lockChangeInfo represents lock changes authored by this view itself, do nothing.
+ CDOLockOwner thisView = CDOLockUtil.createLockOwner(this);
+ if (lockChangeInfo.getLockOwner().equals(thisView))
+ {
+ return;
+ }
+
+ // TODO (CD) I know it is Eike's desideratum that this be done asynchronously.. but beware,
+ // this will require the tests to be fixed to listen for the view events instead of the
+ // session events.
+ updateLockStates(lockChangeInfo.getLockStates());
+ event = lockChangeInfo;
+ }
+ }
+ finally
{
- return;
+ if (event != null)
+ {
+ fireLocksChangedEvent(sender, event);
+ }
}
-
- // TODO (CD) I know it is Eike's desideratum that this be done asynchronously.. but beware,
- // this will require the tests to be fixed to listen for the view events instead of the
- // session events.
- updateLockStates(lockChangeInfo.getLockStates());
- fireLocksChangedEvent(sender, lockChangeInfo);
}
private void fireLocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
@@ -550,11 +575,39 @@ public class CDOViewImpl extends AbstractCDOView
return revisionManager.getRevision(id, branchPoint, initialChunkSize, CDORevision.DEPTH_NONE, loadOnDemand);
}
- public CDOLockState[] getLockStates(Collection<CDOID> ids)
+ public synchronized CDOLockState[] getLockStates(Collection<CDOID> ids)
{
- CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
- CDOLockState[] lockStates = sessionProtocol.getLockStates(viewID, ids);
- return lockStates;
+ List<CDOID> missing = new LinkedList<CDOID>();
+ List<CDOLockState> lockStates = new LinkedList<CDOLockState>();
+ for (CDOID id : ids)
+ {
+ CDOLockState lockState = null;
+ InternalCDOObject obj = getObject(id, false);
+ if (obj != null)
+ {
+ lockState = this.lockStates.get(obj);
+ }
+ if (lockState != null)
+ {
+ lockStates.add(lockState);
+ }
+ else
+ {
+ missing.add(id);
+ }
+ }
+
+ if (missing.size() > 0)
+ {
+ CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
+ CDOLockState[] loadedLockStates = sessionProtocol.getLockStates(viewID, missing);
+ for (CDOLockState loadedLockState : loadedLockStates)
+ {
+ lockStates.add(loadedLockState);
+ }
+ }
+
+ return lockStates.toArray(new CDOLockState[lockStates.size()]);
}
private CDOBranchPoint getBranchPointForID(CDOID id)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java
index 30e92a9..ea310d2 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java
@@ -14,7 +14,6 @@ package org.eclipse.emf.spi.cdo;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.model.CDOPackageTypeRegistry.CDOObjectMarker;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
@@ -56,11 +55,6 @@ public interface InternalCDOObject extends CDOObject, InternalEObject, InternalC
public CDOState cdoInternalSetState(CDOState state);
- /**
- * @since 4.1
- */
- public void cdoInternalSetLockState(CDOLockState lockState);
-
public InternalEObject cdoInternalInstance();
public EStructuralFeature cdoInternalDynamicFeature(int dynamicFeatureID);
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java
index bce3cec..0aa5005 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java
@@ -601,6 +601,23 @@ public final class DBUtil
return result;
}
+ /**
+ * @since 4.1
+ */
+ public static int clearTable(Connection connection, IDBTable table)
+ {
+ return clearTable(connection, table.getName());
+ }
+
+ /**
+ * @since 4.1
+ */
+ public static int clearTable(Connection connection, String tableName)
+ {
+ String sql = "DELETE FROM " + tableName;
+ return update(connection, sql);
+ }
+
public static int select(Connection connection, IDBRowHandler rowHandler, String where, IDBField... fields)
throws DBException
{