Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2016-01-10 11:16:31 +0000
committerEike Stepper2016-01-11 07:59:31 +0000
commite99a56c278527391719d5a44504d1d73791b7eff (patch)
tree95a3698680bb4da39c21928895557154fe7f58d2
parent9f0637117104cd867cccf5deb3e05bb3261eb7a1 (diff)
downloadcdo-e99a56c278527391719d5a44504d1d73791b7eff.tar.gz
cdo-e99a56c278527391719d5a44504d1d73791b7eff.tar.xz
cdo-e99a56c278527391719d5a44504d1d73791b7eff.zip
[485487] Network timeouts can lead to incorrect rollback and stuck session/transaction
https://bugs.eclipse.org/bugs/show_bug.cgi?id=485487
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOModelEditorOpener.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/ResourceGroup.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/wizards/NewWizard.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/properties/ExplorerUIAdapterFactory.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ResetTransactionRequest.java74
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ResetTransactionIndication.java74
-rw-r--r--plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TimeStampAuthority.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java75
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java102
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java31
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalTransaction.java45
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessorBase.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485487_Test.java120
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java36
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java20
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java17
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java91
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java40
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java6
30 files changed, 751 insertions, 127 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
index 731e600bc9..d9196795c5 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
@@ -30,8 +30,9 @@ public interface CDOProtocolConstants
* @since 4.2
* @noreference This field is not intended to be referenced by clients.
*/
- public static final int PROTOCOL_VERSION = 27; // SIGNAL_OPENED_SESSION
+ public static final int PROTOCOL_VERSION = 28; // SIGNAL_RESET_TRANSACTION
+ // public static final int PROTOCOL_VERSION = 27; // SIGNAL_OPENED_SESSION
// public static final int PROTOCOL_VERSION = 26; // Add prefetch depth in LockStateRequest/Indication
// public static final int PROTOCOL_VERSION = 25; // OpenSessionResponse.repositoryAuthenticating
// public static final int PROTOCOL_VERSION = 24; // SIGNAL_LOAD_OBJECT_LIFETIME
@@ -306,6 +307,11 @@ public interface CDOProtocolConstants
*/
public static final short SIGNAL_OPENED_SESSION = 60;
+ /**
+ * @since 4.5
+ */
+ public static final short SIGNAL_RESET_TRANSACTION = 61;
+
// //////////////////////////////////////////////////////////////////////
// Session Refresh
diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOModelEditorOpener.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOModelEditorOpener.java
index 3e926bb4e4..7d9078720d 100644
--- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOModelEditorOpener.java
+++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOModelEditorOpener.java
@@ -25,6 +25,7 @@ import org.eclipse.emf.internal.cdo.transaction.CDOHandlingConflictResolver;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.spi.cdo.CDOMergingConflictResolver;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
@@ -48,6 +49,13 @@ public class CDOModelEditorOpener extends CDOEditorOpener.Default
protected IEditorPart doOpenEditor(final IWorkbenchPage page, URI uri)
{
CDOCheckout checkout = CDOExplorerUtil.getCheckout(uri);
+ if (checkout == null)
+ {
+ MessageDialog.openError(page.getWorkbenchWindow().getShell(), "Error",
+ "The checkout for " + uri + " could not be found.");
+ return null;
+ }
+
final CDOView view = checkout.openView();
if (view instanceof CDOTransaction)
diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/ResourceGroup.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/ResourceGroup.java
index bde71d9f91..ee4aa2d47c 100644
--- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/ResourceGroup.java
+++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/ResourceGroup.java
@@ -80,7 +80,9 @@ public class ResourceGroup extends CDOElement
public void setName(final String name)
{
final String type = getType();
- new Job("Rename " + type.toLowerCase())
+ final String title = "Rename " + type.toLowerCase();
+
+ new Job(title)
{
@Override
protected IStatus run(IProgressMonitor monitor)
@@ -118,7 +120,11 @@ public class ResourceGroup extends CDOElement
if (commitInfo != null)
{
- checkout.getView().waitForUpdate(commitInfo.getTimeStamp());
+ if (!checkout.getView().waitForUpdate(commitInfo.getTimeStamp(), 10000))
+ {
+ OM.LOG.error(title + ": Did not receive an update");
+ return Status.OK_STATUS;
+ }
CDOCheckoutManagerImpl checkoutManager = (CDOCheckoutManagerImpl)CDOExplorerUtil.getCheckoutManager();
checkoutManager.fireElementChangedEvent(ElementsChangedEvent.StructuralImpact.PARENT,
diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/wizards/NewWizard.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/wizards/NewWizard.java
index b3691d5fe8..78dc864993 100644
--- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/wizards/NewWizard.java
+++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/wizards/NewWizard.java
@@ -87,6 +87,7 @@ public abstract class NewWizard extends Wizard implements INewWizard
{
final Object parent = page.getParent();
final String name = page.getName();
+ final String error = "An error occured while creating the " + title.toLowerCase() + ".";
new Job(title)
{
@@ -139,8 +140,7 @@ public abstract class NewWizard extends Wizard implements INewWizard
{
public void run()
{
- ErrorDialog.openError(getShell(), "Error",
- "An error occured while creating the " + title.toLowerCase() + ".", status);
+ ErrorDialog.openError(getShell(), "Error", error, status);
}
});
@@ -154,7 +154,11 @@ public abstract class NewWizard extends Wizard implements INewWizard
if (commitInfo != null && contentProvider != null)
{
CDOView view = checkout.getView();
- view.waitForUpdate(commitInfo.getTimeStamp());
+ if (!view.waitForUpdate(commitInfo.getTimeStamp(), 10000))
+ {
+ OM.LOG.error(error + " Did not receive an update");
+ return Status.OK_STATUS;
+ }
CDOObject newObject = view.getObject(newID);
contentProvider.selectObjects(newObject);
diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/properties/ExplorerUIAdapterFactory.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/properties/ExplorerUIAdapterFactory.java
index dbba91d79a..90be3ab992 100644
--- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/properties/ExplorerUIAdapterFactory.java
+++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/properties/ExplorerUIAdapterFactory.java
@@ -194,7 +194,9 @@ public class ExplorerUIAdapterFactory implements IAdapterFactory
public void setName(final String name)
{
- new Job("Rename " + getType().toLowerCase())
+ final String title = "Rename " + getType().toLowerCase();
+
+ new Job(title)
{
@Override
protected IStatus run(IProgressMonitor monitor)
@@ -232,7 +234,11 @@ public class ExplorerUIAdapterFactory implements IAdapterFactory
if (commitInfo != null && checkout != null)
{
- checkout.getView().waitForUpdate(commitInfo.getTimeStamp());
+ if (!checkout.getView().waitForUpdate(commitInfo.getTimeStamp(), 10000))
+ {
+ OM.LOG.error(title + ": Did not receive an update");
+ return Status.OK_STATUS;
+ }
CDOCheckoutManagerImpl checkoutManager = (CDOCheckoutManagerImpl)CDOExplorerUtil.getCheckoutManager();
checkoutManager.fireElementChangedEvent(ElementsChangedEvent.StructuralImpact.PARENT, resourceNode);
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
index b4c17ddbe6..2e6f609394 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
@@ -21,6 +21,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPointRange;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
@@ -461,6 +462,11 @@ public class CDOClientProtocol extends AuthenticatingSignalProtocol<CDOSessionIm
return send(new CommitXATransactionCancelRequest(this, xaContext), monitor);
}
+ public CDOCommitInfo resetTransaction(int transactionID, int commitNumber)
+ {
+ return send(new ResetTransactionRequest(this, transactionID, commitNumber));
+ }
+
public List<CDORemoteSession> getRemoteSessions(InternalCDORemoteSessionManager manager, boolean subscribe)
{
return send(new GetRemoteSessionsRequest(this, subscribe));
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java
index 25ef8f885c..a891df1530 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CommitTransactionRequest.java
@@ -38,7 +38,6 @@ import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.security.CDOPermission;
import org.eclipse.emf.cdo.internal.net4j.bundle.OM;
import org.eclipse.emf.cdo.session.CDORepositoryInfo;
-import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.internal.cdo.object.CDOObjectReferenceImpl;
import org.eclipse.emf.internal.cdo.view.AbstractCDOView;
@@ -51,6 +50,8 @@ import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult;
+import org.eclipse.emf.spi.cdo.InternalCDOSession.CommitToken;
+import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction.InternalCDOCommitContext;
import java.io.IOException;
@@ -70,7 +71,9 @@ public class CommitTransactionRequest extends CDOClientRequestWithMonitoring<Com
private CDOIDProvider idProvider; // CDOTransaction
- private String comment;
+ private int commitNumber;
+
+ private String commitComment;
private boolean releaseLocks;
@@ -85,7 +88,7 @@ public class CommitTransactionRequest extends CDOClientRequestWithMonitoring<Com
/**
* Is <code>null</code> in {@link CommitDelegationRequest}.
*/
- private CDOTransaction transaction;
+ private InternalCDOTransaction transaction;
private boolean clearResourcePathCache;
@@ -99,7 +102,13 @@ public class CommitTransactionRequest extends CDOClientRequestWithMonitoring<Com
super(protocol, signalID);
transaction = context.getTransaction();
- comment = context.getCommitComment();
+ CommitToken commitToken = transaction.getCommitToken();
+ if (commitToken != null)
+ {
+ commitNumber = commitToken.getCommitNumber();
+ }
+
+ commitComment = context.getCommitComment();
releaseLocks = context.isAutoReleaseLocks();
idProvider = context.getTransaction();
commitData = context.getCommitData();
@@ -142,7 +151,8 @@ public class CommitTransactionRequest extends CDOClientRequestWithMonitoring<Com
out.writeLong(getLastUpdateTime());
out.writeBoolean(releaseLocks);
- out.writeString(comment);
+ out.writeInt(commitNumber);
+ out.writeString(commitComment);
out.writeInt(newPackageUnits.size());
out.writeInt(locksOnNewObjects.size());
out.writeInt(newObjects.size());
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ResetTransactionRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ResetTransactionRequest.java
new file mode 100644
index 0000000000..140bd4c873
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ResetTransactionRequest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 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.internal.net4j.protocol;
+
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.protocol.CDODataInput;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.internal.net4j.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ */
+public class ResetTransactionRequest extends CDOClientRequest<CDOCommitInfo>
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, ResetTransactionRequest.class);
+
+ private int transactionID;
+
+ private int commitNumber;
+
+ public ResetTransactionRequest(CDOClientProtocol protocol, int transactionID, int commitNumber)
+ {
+ super(protocol, CDOProtocolConstants.SIGNAL_RESET_TRANSACTION);
+ this.transactionID = transactionID;
+ this.commitNumber = commitNumber;
+ }
+
+ @Override
+ protected void requesting(CDODataOutput out) throws IOException
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing transactionID: {0}", transactionID); //$NON-NLS-1$
+ }
+
+ out.writeInt(transactionID);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing commitNumber: {0}", commitNumber); //$NON-NLS-1$
+ }
+
+ out.writeInt(commitNumber);
+ }
+
+ @Override
+ protected CDOCommitInfo confirming(CDODataInput in) throws IOException
+ {
+ if (in.readBoolean())
+ {
+ long timeStamp = in.readLong();
+ long previousTimeStamp = in.readLong();
+
+ InternalCDOCommitInfoManager commitInfoManager = getSession().getCommitInfoManager();
+ return commitInfoManager.createCommitInfo(null, timeStamp, previousTimeStamp, null, null, null);
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java
index 941aeea198..abf8fb61a0 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateRawCommitContext.java
@@ -320,6 +320,10 @@ public class HibernateRawCommitContext implements InternalCommitContext
{
}
+ public void setCommitNumber(int commitNumber)
+ {
+ }
+
public void setCommitComment(String comment)
{
}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java
index f51a2fb386..158ec41677 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java
@@ -388,6 +388,9 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement
case SIGNAL_OPENED_SESSION:
return new OpenedSessionNotification(this);
+ case SIGNAL_RESET_TRANSACTION:
+ return new ResetTransactionIndication(this);
+
default:
return super.createSignalReactor(signalID);
}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java
index ca070cc81d..8a1c87ca88 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitTransactionIndication.java
@@ -106,7 +106,11 @@ public class CommitTransactionIndication extends CDOServerIndicationWithMonitori
}
catch (Exception ex)
{
- OM.LOG.error(ex);
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(ex);
+ }
+
throw WrappedException.wrap(ex);
}
finally
@@ -123,6 +127,7 @@ public class CommitTransactionIndication extends CDOServerIndicationWithMonitori
long lastUpdateTime = in.readLong();
boolean autoReleaseLocksEnabled = in.readBoolean();
+ int commitNumber = in.readInt();
String commitComment = in.readString();
InternalCDOPackageUnit[] newPackageUnits = new InternalCDOPackageUnit[in.readInt()];
@@ -267,6 +272,7 @@ public class CommitTransactionIndication extends CDOServerIndicationWithMonitori
detachedObjectTypes = null;
}
+ commitContext.setCommitNumber(commitNumber);
commitContext.setLastUpdateTime(lastUpdateTime);
commitContext.setAutoReleaseLocksEnabled(autoReleaseLocksEnabled);
commitContext.setClearResourcePathCache(clearResourcePathCache);
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ResetTransactionIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ResetTransactionIndication.java
new file mode 100644
index 0000000000..fa45694a26
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ResetTransactionIndication.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 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.server.internal.net4j.protocol;
+
+import org.eclipse.emf.cdo.common.protocol.CDODataInput;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM;
+import org.eclipse.emf.cdo.spi.server.InternalSession;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction.CommitAttempt;
+
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ */
+public class ResetTransactionIndication extends CDOServerReadIndication
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, ResetTransactionIndication.class);
+
+ private int transactionID;
+
+ private int commitNumber;
+
+ public ResetTransactionIndication(CDOServerProtocol protocol)
+ {
+ super(protocol, CDOProtocolConstants.SIGNAL_RESET_TRANSACTION);
+ }
+
+ @Override
+ protected void indicating(CDODataInput in) throws IOException
+ {
+ transactionID = in.readInt();
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read transactionID: {0}", transactionID); //$NON-NLS-1$
+ }
+
+ commitNumber = in.readInt();
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read commitNumber: {0}", commitNumber); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ protected void responding(CDODataOutput out) throws IOException
+ {
+ InternalSession session = getSession();
+ InternalTransaction transaction = (InternalTransaction)session.getView(transactionID);
+ CommitAttempt lastCommitSuccess = transaction.getLastCommitAttempt();
+ if (lastCommitSuccess != null && lastCommitSuccess.getCommitNumber() == commitNumber)
+ {
+ out.writeBoolean(true);
+ out.writeLong(lastCommitSuccess.getTimeStamp());
+ out.writeLong(lastCommitSuccess.getPreviousTimeStamp());
+ }
+ else
+ {
+ out.writeBoolean(false);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java
index 4ccb325c6a..b7dbe912c9 100644
--- a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java
+++ b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java
@@ -69,6 +69,7 @@ import org.eclipse.net4j.connector.IConnector;
import org.eclipse.net4j.util.ArrayUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.HashBag;
+import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
import org.eclipse.net4j.util.container.ContainerEventAdapter;
import org.eclipse.net4j.util.container.IContainer;
import org.eclipse.net4j.util.container.IManagedContainer;
@@ -407,7 +408,10 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage
if (waitUntilReadable)
{
- systemView.waitForUpdate(commit.getTimeStamp());
+ if (!systemView.waitForUpdate(commit.getTimeStamp(), 10000))
+ {
+ throw new TimeoutRuntimeException();
+ }
}
}
catch (CommitException ex)
@@ -686,7 +690,11 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage
{
if (lastRealmModification != CDOBranchPoint.UNSPECIFIED_DATE)
{
- systemView.waitForUpdate(lastRealmModification);
+ if (!systemView.waitForUpdate(lastRealmModification, 10000L))
+ {
+ throw new TimeoutRuntimeException();
+ }
+
lastRealmModification = CDOBranchPoint.UNSPECIFIED_DATE;
}
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 6d3c997efb..a6af0e1ddd 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
@@ -72,6 +72,10 @@ class TimeStampAuthority
this.repository = repository;
}
+ /**
+ * @deprecated Not used anymore.
+ */
+ @Deprecated
synchronized long[] startCommit(OMMonitor monitor)
{
return startCommit(CDOBranchPoint.UNSPECIFIED_DATE, monitor);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java
index 58d300a6d0..96e8c54b3e 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java
@@ -26,6 +26,8 @@ import org.eclipse.net4j.util.om.monitor.OMMonitor;
*/
public class Transaction extends View implements InternalTransaction
{
+ private CommitAttempt lastCommitAttempt;
+
public Transaction(InternalSession session, int viewID, CDOBranchPoint branchPoint)
{
super(session, viewID, branchPoint);
@@ -73,6 +75,16 @@ public class Transaction extends View implements InternalTransaction
};
}
+ public CommitAttempt getLastCommitAttempt()
+ {
+ return lastCommitAttempt;
+ }
+
+ public void setLastCommitAttempt(CommitAttempt lastCommitAttempt)
+ {
+ this.lastCommitAttempt = lastCommitAttempt;
+ }
+
@Override
protected void validateTimeStamp(long timeStamp) throws IllegalArgumentException
{
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 3fbe135d4b..e87ac6a685 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
@@ -70,6 +70,7 @@ import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction.CommitAttempt;
import org.eclipse.net4j.util.CheckUtil;
import org.eclipse.net4j.util.StringUtil;
@@ -132,6 +133,8 @@ public class TransactionCommitContext implements InternalCommitContext
private long previousTimeStamp = CDORevision.UNSPECIFIED_DATE;
+ private int commitNumber;
+
private String commitComment;
private boolean usingEcore;
@@ -216,6 +219,11 @@ public class TransactionCommitContext implements InternalCommitContext
return transaction.getSession().getUserID();
}
+ public int getCommitNumber()
+ {
+ return commitNumber;
+ }
+
public String getCommitComment()
{
return commitComment;
@@ -354,7 +362,7 @@ public class TransactionCommitContext implements InternalCommitContext
return (InternalCDORevision)transaction.getRevision(id);
}
- private Map<CDOID, InternalCDORevision> cacheRevisions()
+ protected Map<CDOID, InternalCDORevision> cacheRevisions()
{
Map<CDOID, InternalCDORevision> cache = CDOIDUtil.createMap();
if (newObjects != null)
@@ -432,7 +440,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void applyIDMappings(InternalCDORevision[] revisions, OMMonitor monitor)
+ protected void applyIDMappings(InternalCDORevision[] revisions, OMMonitor monitor)
{
try
{
@@ -544,6 +552,11 @@ public class TransactionCommitContext implements InternalCommitContext
autoReleaseLocksEnabled = on;
}
+ public void setCommitNumber(int commitNumber)
+ {
+ this.commitNumber = commitNumber;
+ }
+
public void setCommitComment(String commitComment)
{
this.commitComment = commitComment;
@@ -583,7 +596,7 @@ public class TransactionCommitContext implements InternalCommitContext
return old;
}
- private InternalCDOPackageUnit[] lockPackageRegistry(InternalCDOPackageUnit[] packageUnits)
+ protected InternalCDOPackageUnit[] lockPackageRegistry(InternalCDOPackageUnit[] packageUnits)
throws InterruptedException
{
if (!packageRegistryLocked)
@@ -648,7 +661,7 @@ public class TransactionCommitContext implements InternalCommitContext
monitor.worked();
detachObjects(monitor.fork());
- accessor.write(this, monitor.fork(100));
+ writeAccessor(monitor.fork(100));
}
catch (RollbackException ex)
{
@@ -702,7 +715,7 @@ public class TransactionCommitContext implements InternalCommitContext
return postCommitLockStates;
}
- private void handleException(Throwable ex)
+ protected void handleException(Throwable ex)
{
try
{
@@ -742,7 +755,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void finishMonitor(OMMonitor monitor)
+ protected void finishMonitor(OMMonitor monitor)
{
try
{
@@ -760,12 +773,14 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void setTimeStamp(OMMonitor monitor)
+ protected void setTimeStamp(OMMonitor monitor)
{
long[] times = createTimeStamp(monitor); // Could throw an exception
timeStamp = times[0];
previousTimeStamp = times[1];
CheckUtil.checkState(timeStamp != CDOBranchPoint.UNSPECIFIED_DATE, "Commit timestamp must not be 0");
+
+ transaction.setLastCommitAttempt(new CommitAttempt(commitNumber, timeStamp, previousTimeStamp));
}
protected long[] createTimeStamp(OMMonitor monitor)
@@ -791,9 +806,16 @@ public class TransactionCommitContext implements InternalCommitContext
public void postCommit(boolean success)
{
- if (packageRegistryLocked)
+ try
{
- repository.getPackageRegistryCommitLock().release();
+ if (packageRegistryLocked)
+ {
+ repository.getPackageRegistryCommitLock().release();
+ }
+ }
+ catch (Throwable ex)
+ {
+ OM.LOG.warn("A problem occured while releasing the package registry commit lock", ex);
}
try
@@ -804,7 +826,7 @@ public class TransactionCommitContext implements InternalCommitContext
sendCommitNotifications(success);
}
}
- catch (Exception ex)
+ catch (Throwable ex)
{
OM.LOG.warn("A problem occured while notifying other sessions", ex);
}
@@ -822,7 +844,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void sendCommitNotifications(boolean success)
+ protected void sendCommitNotifications(boolean success)
{
commitNotificationInfo.setSender(transaction.getSession());
commitNotificationInfo.setRevisionProvider(this);
@@ -853,7 +875,7 @@ public class TransactionCommitContext implements InternalCommitContext
return new FailureCommitInfo(timeStamp, previousTimeStamp);
}
- private CDOCommitData createCommitData()
+ protected CDOCommitData createCommitData()
{
List<CDOPackageUnit> newPackageUnitsCollection = new IndexedList.ArrayBacked<CDOPackageUnit>()
{
@@ -1034,7 +1056,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void lockTarget(Object value, Set<CDOID> newIDs, boolean supportingBranches)
+ protected void lockTarget(Object value, Set<CDOID> newIDs, boolean supportingBranches)
{
if (value instanceof CDOIDObject)
{
@@ -1069,7 +1091,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private synchronized void unlockObjects()
+ protected synchronized void unlockObjects()
{
// Unlock objects locked during commit
if (!lockedObjects.isEmpty())
@@ -1113,7 +1135,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void computeDirtyObjects(OMMonitor monitor)
+ protected void computeDirtyObjects(OMMonitor monitor)
{
try
{
@@ -1140,7 +1162,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private InternalCDORevision computeDirtyObject(InternalCDORevisionDelta delta)
+ protected InternalCDORevision computeDirtyObject(InternalCDORevisionDelta delta)
{
CDOID id = delta.getID();
@@ -1228,7 +1250,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private boolean isTheRootReachable(InternalCDORevision revision, Set<CDOID> objectsThatReachTheRoot,
+ protected boolean isTheRootReachable(InternalCDORevision revision, Set<CDOID> objectsThatReachTheRoot,
Set<CDOID> visited)
{
CDOID id = revision.getID();
@@ -1305,7 +1327,7 @@ public class TransactionCommitContext implements InternalCommitContext
return accessor;
}
- private void updateInfraStructure(OMMonitor monitor)
+ protected void updateInfraStructure(OMMonitor monitor)
{
try
{
@@ -1345,7 +1367,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void applyLocksOnNewObjects() throws InterruptedException
+ protected void applyLocksOnNewObjects() throws InterruptedException
{
final CDOLockOwner owner = CDOLockUtil.createLockOwner(transaction);
@@ -1373,7 +1395,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void sendLockNotifications(List<LockState<Object, IView>> newLockStates)
+ protected void sendLockNotifications(List<LockState<Object, IView>> newLockStates)
{
CDOLockState[] newStates = Repository.toCDOLockStates(newLockStates);
@@ -1384,7 +1406,7 @@ public class TransactionCommitContext implements InternalCommitContext
repository.getSessionManager().sendLockNotification(transaction.getSession(), info);
}
- private void addNewPackageUnits(OMMonitor monitor)
+ protected void addNewPackageUnits(OMMonitor monitor)
{
InternalCDOPackageRegistry repositoryPackageRegistry = repository.getPackageRegistry(false);
synchronized (repositoryPackageRegistry)
@@ -1408,7 +1430,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void addRevisions(CDORevision[] revisions, OMMonitor monitor)
+ protected void addRevisions(CDORevision[] revisions, OMMonitor monitor)
{
try
{
@@ -1431,7 +1453,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void reviseDetachedObjects(OMMonitor monitor)
+ protected void reviseDetachedObjects(OMMonitor monitor)
{
try
{
@@ -1453,7 +1475,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
- private void detachObjects(OMMonitor monitor)
+ protected void detachObjects(OMMonitor monitor)
{
int size = detachedObjects.length;
cachedDetachedRevisions = new InternalCDORevision[size];
@@ -1480,6 +1502,11 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
+ protected void writeAccessor(OMMonitor monitor)
+ {
+ accessor.write(this, monitor);
+ }
+
@Override
public String toString()
{
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java
index a038d9c92c..75db50bbc4 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java
@@ -21,6 +21,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPointRange;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
@@ -559,6 +560,11 @@ public class EmbeddedClientSessionProtocol extends Lifecycle implements CDOSessi
throw new UnsupportedOperationException();
}
+ public CDOCommitInfo resetTransaction(int transactionID, int commitNumber)
+ {
+ throw new UnsupportedOperationException();
+ }
+
public List<CDORemoteSession> getRemoteSessions(InternalCDORemoteSessionManager manager, boolean subscribe)
{
throw new UnsupportedOperationException();
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java
index 657ca3b19e..8fc9fcd490 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java
@@ -65,6 +65,8 @@ import java.util.Set;
*/
public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, DurableLocking2, BranchLoader3
{
+ private final MEMStore store;
+
private final IQueryHandler testQueryHandler = new IQueryHandler()
{
public void executeQuery(CDOQueryInfo info, IQueryContext queryContext)
@@ -105,7 +107,7 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
}
int i = 0;
- for (InternalCDORevision revision : getStore().getCurrentRevisions())
+ for (InternalCDORevision revision : store.getCurrentRevisions())
{
if (sleep != null)
{
@@ -168,11 +170,12 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
}
};
- private List<InternalCDORevision> newRevisions = new ArrayList<InternalCDORevision>();
+ private List<InternalCDORevision> newRevisions;
public MEMStoreAccessor(MEMStore store, ISession session)
{
super(store, session);
+ this.store = store;
}
/**
@@ -181,12 +184,13 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
public MEMStoreAccessor(MEMStore store, ITransaction transaction)
{
super(store, transaction);
+ this.store = store;
}
@Override
public MEMStore getStore()
{
- return (MEMStore)super.getStore();
+ return store;
}
/**
@@ -209,22 +213,22 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
{
- return getStore().createBranch(branchID, branchInfo);
+ return store.createBranch(branchID, branchInfo);
}
public BranchInfo loadBranch(int branchID)
{
- return getStore().loadBranch(branchID);
+ return store.loadBranch(branchID);
}
public SubBranchInfo[] loadSubBranches(int branchID)
{
- return getStore().loadSubBranches(branchID);
+ return store.loadSubBranches(branchID);
}
public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
{
- return getStore().loadBranches(startID, endID, branchHandler);
+ return store.loadBranches(startID, endID, branchHandler);
}
@Deprecated
@@ -241,35 +245,35 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
public void renameBranch(int branchID, String oldName, String newName)
{
- getStore().renameBranch(branchID, oldName, newName);
+ store.renameBranch(branchID, oldName, newName);
}
public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
{
- getStore().loadCommitInfos(branch, startTime, endTime, handler);
+ store.loadCommitInfos(branch, startTime, endTime, handler);
}
public Set<CDOID> readChangeSet(OMMonitor monitor, CDOChangeSetSegment... segments)
{
- return getStore().readChangeSet(segments);
+ return store.readChangeSet(segments);
}
public InternalCDORevision readRevision(CDOID id, CDOBranchPoint branchPoint, int listChunk,
CDORevisionCacheAdder cache)
{
- return getStore().getRevision(id, branchPoint);
+ return store.getRevision(id, branchPoint);
}
public InternalCDORevision readRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int listChunk,
CDORevisionCacheAdder cache)
{
- return getStore().getRevisionByVersion(id, branchVersion);
+ return store.getRevisionByVersion(id, branchVersion);
}
public void handleRevisions(EClass eClass, CDOBranch branch, long timeStamp, boolean exactTime,
CDORevisionHandler handler)
{
- getStore().handleRevisions(eClass, branch, timeStamp, exactTime, handler);
+ store.handleRevisions(eClass, branch, timeStamp, exactTime, handler);
}
/**
@@ -278,13 +282,12 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
@Override
protected void doCommit(OMMonitor monitor)
{
- // Do nothing
+ newRevisions = null;
}
@Override
public void doWrite(InternalCommitContext context, OMMonitor monitor)
{
- MEMStore store = getStore();
synchronized (store)
{
super.doWrite(context, monitor);
@@ -295,18 +298,20 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
protected void writeCommitInfo(CDOBranch branch, long timeStamp, long previousTimeStamp, String userID,
String comment, OMMonitor monitor)
{
- getStore().addCommitInfo(branch, timeStamp, previousTimeStamp, userID, comment);
+ store.addCommitInfo(branch, timeStamp, previousTimeStamp, userID, comment);
}
@Override
protected void doRollback(CommitContext context)
{
- MEMStore store = getStore();
- synchronized (store)
+ if (newRevisions != null)
{
- for (InternalCDORevision revision : newRevisions)
+ synchronized (store)
{
- store.rollbackRevision(revision);
+ for (InternalCDORevision revision : newRevisions)
+ {
+ store.rollbackRevision(revision);
+ }
}
}
}
@@ -327,8 +332,13 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
protected void writeRevision(InternalCDORevision revision)
{
+ if (newRevisions == null)
+ {
+ newRevisions = new ArrayList<InternalCDORevision>();
+ }
+
newRevisions.add(revision);
- getStore().addRevision(revision, false);
+ store.addRevision(revision, false);
}
/**
@@ -350,7 +360,7 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
protected void writeRevisionDelta(InternalCDORevisionDelta revisionDelta, CDOBranch branch, long created)
{
CDOID id = revisionDelta.getID();
- InternalCDORevision revision = getStore().getRevisionByVersion(id, revisionDelta);
+ InternalCDORevision revision = store.getRevisionByVersion(id, revisionDelta);
if (revision == null)
{
throw new ConcurrentModificationException("Trying to update object " + id //$NON-NLS-1$
@@ -378,7 +388,7 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
*/
protected void detachObject(CDOID id, CDOBranch branch, long timeStamp)
{
- getStore().detachObject(id, branch, timeStamp);
+ store.detachObject(id, branch, timeStamp);
}
/**
@@ -386,12 +396,12 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
*/
public void queryResources(QueryResourcesContext context)
{
- getStore().queryResources(context);
+ store.queryResources(context);
}
public void queryXRefs(QueryXRefsContext context)
{
- getStore().queryXRefs(context);
+ store.queryXRefs(context);
}
public IQueryHandler getQueryHandler(CDOQueryInfo info)
@@ -407,13 +417,13 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
public void rawExport(CDODataOutput out, int fromBranchID, int toBranchID, long fromCommitTime, long toCommitTime)
throws IOException
{
- getStore().rawExport(out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);
+ store.rawExport(out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);
}
public void rawImport(CDODataInput in, int fromBranchID, int toBranchID, long fromCommitTime, long toCommitTime,
OMMonitor monitor) throws IOException
{
- getStore().rawImport(in, fromBranchID, toBranchID, fromCommitTime, toCommitTime, monitor);
+ store.rawImport(in, fromBranchID, toBranchID, fromCommitTime, toCommitTime, monitor);
}
public void rawStore(InternalCDOPackageUnit[] packageUnits, OMMonitor monitor)
@@ -423,7 +433,7 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
public void rawStore(InternalCDORevision revision, OMMonitor monitor)
{
- getStore().addRevision(revision, true);
+ store.addRevision(revision, true);
}
public void rawStore(byte[] id, long size, InputStream inputStream) throws IOException
@@ -444,7 +454,7 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
public void rawDelete(CDOID id, int version, CDOBranch branch, EClass eClass, OMMonitor monitor)
{
- getStore().rawDelete(id, version, branch);
+ store.rawDelete(id, version, branch);
}
public void rawCommit(double commitWork, OMMonitor monitor)
@@ -455,75 +465,75 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
public LockArea createLockArea(String userID, CDOBranchPoint branchPoint, boolean readOnly,
Map<CDOID, LockGrade> locks)
{
- return getStore().createLockArea(userID, branchPoint, readOnly, locks);
+ return store.createLockArea(userID, branchPoint, readOnly, locks);
}
public LockArea createLockArea(String durableLockingID, String userID, CDOBranchPoint branchPoint, boolean readOnly,
Map<CDOID, LockGrade> locks)
{
- return getStore().createLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
+ return store.createLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
}
public void updateLockArea(LockArea lockArea)
{
- getStore().updateLockArea(lockArea);
+ store.updateLockArea(lockArea);
}
public LockArea getLockArea(String durableLockingID) throws LockAreaNotFoundException
{
- return getStore().getLockArea(durableLockingID);
+ return store.getLockArea(durableLockingID);
}
public void getLockAreas(String userIDPrefix, Handler handler)
{
- getStore().getLockAreas(userIDPrefix, handler);
+ store.getLockAreas(userIDPrefix, handler);
}
public void deleteLockArea(String durableLockingID)
{
- getStore().deleteLockArea(durableLockingID);
+ store.deleteLockArea(durableLockingID);
}
public void lock(String durableLockingID, LockType type, Collection<? extends Object> objectsToLock)
{
- getStore().lock(durableLockingID, type, objectsToLock);
+ store.lock(durableLockingID, type, objectsToLock);
}
public void unlock(String durableLockingID, LockType type, Collection<? extends Object> objectsToUnlock)
{
- getStore().unlock(durableLockingID, type, objectsToUnlock);
+ store.unlock(durableLockingID, type, objectsToUnlock);
}
public void unlock(String durableLockingID)
{
- getStore().unlock(durableLockingID);
+ store.unlock(durableLockingID);
}
public void queryLobs(List<byte[]> ids)
{
- getStore().queryLobs(ids);
+ store.queryLobs(ids);
}
public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
{
- getStore().handleLobs(fromTime, toTime, handler);
+ store.handleLobs(fromTime, toTime, handler);
}
public void loadLob(byte[] id, OutputStream out) throws IOException
{
- getStore().loadLob(id, out);
+ store.loadLob(id, out);
}
@Override
protected void writeBlob(byte[] id, long size, InputStream inputStream) throws IOException
{
- getStore().writeBlob(id, size, inputStream);
+ store.writeBlob(id, size, inputStream);
}
@Override
protected void writeClob(byte[] id, long size, Reader reader) throws IOException
{
- getStore().writeClob(id, size, reader);
+ store.writeClob(id, size, reader);
}
@Override
@@ -535,7 +545,11 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
@Override
protected void doDeactivate() throws Exception
{
- newRevisions.clear();
+ if (newRevisions != null)
+ {
+ newRevisions.clear();
+ newRevisions = null;
+ }
}
@Override
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 8be293f5d4..791be4692f 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
@@ -72,6 +72,7 @@ import org.eclipse.emf.cdo.spi.server.SyncingUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.IndexedList;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.Monitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
@@ -735,7 +736,10 @@ public abstract class SynchronizableRepository extends Repository.Default implem
}
long requiredTimestamp = masterLockingResult.getRequiredTimestamp();
- remoteSession.waitForUpdate(requiredTimestamp);
+ if (!remoteSession.waitForUpdate(requiredTimestamp, 10000))
+ {
+ throw new TimeoutRuntimeException();
+ }
}
return masterLockingResult;
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java
index 0f8824485d..d304a713df 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalCommitContext.java
@@ -49,20 +49,20 @@ public interface InternalCommitContext extends IStoreAccessor.CommitContext, CDO
}
}, //
- new ProgressDistributable.Default<InternalCommitContext>()
- {
- public void runLoop(int index, InternalCommitContext commitContext, OMMonitor monitor) throws Exception
- {
- if (commitContext.getRollbackMessage() == null)
- {
- commitContext.commit(monitor.fork());
- }
- else
+ new ProgressDistributable.Default<InternalCommitContext>()
{
- monitor.worked();
- }
- }
- });
+ public void runLoop(int index, InternalCommitContext commitContext, OMMonitor monitor) throws Exception
+ {
+ if (commitContext.getRollbackMessage() == null)
+ {
+ commitContext.commit(monitor.fork());
+ }
+ else
+ {
+ monitor.worked();
+ }
+ }
+ });
public InternalTransaction getTransaction();
@@ -136,6 +136,11 @@ public interface InternalCommitContext extends IStoreAccessor.CommitContext, CDO
public void setAutoReleaseLocksEnabled(boolean on);
+ /**
+ * @since 4.5
+ */
+ public void setCommitNumber(int commitNumber);
+
public void setCommitComment(String comment);
/**
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalTransaction.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalTransaction.java
index 0d8655e426..4488c03a06 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalTransaction.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalTransaction.java
@@ -23,4 +23,49 @@ import org.eclipse.emf.cdo.server.ITransaction;
public interface InternalTransaction extends ITransaction, InternalView
{
public InternalCommitContext createCommitContext();
+
+ /**
+ * @since 4.5
+ */
+ public CommitAttempt getLastCommitAttempt();
+
+ /**
+ * @since 4.5
+ */
+ public void setLastCommitAttempt(CommitAttempt lastCommitAttempt);
+
+ /**
+ * @author Eike Stepper
+ * @since 4.5
+ */
+ public static final class CommitAttempt
+ {
+ private final int commitNumber;
+
+ private final long timeStamp;
+
+ private final long previousTimeStamp;
+
+ public CommitAttempt(int commitNumber, long timeStamp, long previousTimeStamp)
+ {
+ this.commitNumber = commitNumber;
+ this.timeStamp = timeStamp;
+ this.previousTimeStamp = previousTimeStamp;
+ }
+
+ public int getCommitNumber()
+ {
+ return commitNumber;
+ }
+
+ public long getTimeStamp()
+ {
+ return timeStamp;
+ }
+
+ public long getPreviousTimeStamp()
+ {
+ return previousTimeStamp;
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessorBase.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessorBase.java
index adbd4024e2..0d3b4a823d 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessorBase.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/StoreAccessorBase.java
@@ -67,8 +67,6 @@ public abstract class StoreAccessorBase extends Lifecycle implements IStoreAcces
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, StoreAccessorBase.class);
- // private static int COUNT;
-
private Store store;
private Object context;
@@ -264,18 +262,6 @@ public abstract class StoreAccessorBase extends Lifecycle implements IStoreAcces
protected abstract CDOID getNextCDOID(CDORevision revision);
- // @Override
- // protected void doActivate() throws Exception
- // {
- // System.out.println("Active accessors: " + ++COUNT);
- // }
- //
- // @Override
- // protected void doDeactivate() throws Exception
- // {
- // System.out.println("Active accessors: " + --COUNT);
- // }
-
protected void doPassivate() throws Exception
{
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485487_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485487_Test.java
new file mode 100644
index 0000000000..d724ae69e9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_485487_Test.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016 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.internal.server.Repository;
+import org.eclipse.emf.cdo.internal.server.TransactionCommitContext;
+import org.eclipse.emf.cdo.net4j.CDONet4jSession;
+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.impl.RepositoryConfig;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CommitException;
+
+import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+import java.util.Map;
+
+/**
+ * Bug 485487.
+ *
+ * @author Eike Stepper
+ */
+public class Bugzilla_485487_Test extends AbstractCDOTest
+{
+ private static final String REPOSITORY_NAME = "repo1";
+
+ private Repository repository;
+
+ private boolean forceTimeout;
+
+ @Override
+ protected void doSetUp() throws Exception
+ {
+ createRepository();
+ super.doSetUp();
+ }
+
+ private void createRepository()
+ {
+ repository = new Repository.Default()
+ {
+ @Override
+ public InternalCommitContext createCommitContext(InternalTransaction transaction)
+ {
+ return new TransactionCommitContext(transaction)
+ {
+ @Override
+ protected void writeAccessor(OMMonitor monitor)
+ {
+ super.writeAccessor(monitor);
+
+ if (forceTimeout)
+ {
+ ConcurrencyUtil.sleep(2000);
+ }
+ }
+ };
+ }
+ };
+
+ Map<String, String> props = getRepositoryProperties();
+ ((InternalRepository)repository).setProperties(props);
+
+ repository.setName(REPOSITORY_NAME);
+
+ Map<String, Object> map = getTestProperties();
+ map.put(RepositoryConfig.PROP_TEST_REPOSITORY, repository);
+ map.put(RepositoryConfig.PROP_TEST_ENABLE_SERVER_BROWSER, true);
+ }
+
+ @CleanRepositoriesBefore(reason = "Isolated repository needed")
+ @CleanRepositoriesAfter(reason = "Isolated repository needed")
+ public void testTimeoutDuringCommit() throws Exception
+ {
+ disableConsole();
+
+ CDONet4jSession session = (CDONet4jSession)openSession(REPOSITORY_NAME);
+ session.options().setCommitTimeout(1);
+
+ CDOTransaction transaction = session.openTransaction();
+ transaction.options().setCommitInfoTimeout(1000);
+ transaction.createResource(getResourcePath("/test1"));
+
+ msg("#### Commit-1");
+
+ try
+ {
+ forceTimeout = true;
+ transaction.setCommitComment("test1");
+ transaction.commit();
+ fail("CommitException expected");
+ }
+ catch (CommitException expected)
+ {
+ assertEquals(true, expected.getMessage().contains("Timeout after"));
+ }
+
+ msg("#### Rollback");
+
+ forceTimeout = false;
+ transaction.rollback();
+
+ transaction.createResource(getResourcePath("/test2"));
+
+ msg("#### Commit-2");
+ transaction.setCommitComment("test2");
+ transaction.commit();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java
index 3becc9c982..4431348634 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java
@@ -230,6 +230,11 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr
public static final CDOUndoDetector DEFAULT_UNDO_DETECTOR = CDOUndoDetector.ALL_FEATURES;
/**
+ * @since 4.5
+ */
+ public static final long DEFAULT_COMMIT_INFO_TIMEOUT = 10000;
+
+ /**
* Returns the {@link CDOTransaction transaction} of this options object.
*
* @since 4.0
@@ -305,6 +310,24 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr
public void setAutoReleaseLocksEnabled(boolean on);
/**
+ * Returns the number of milliseconds to wait for the transaction update when {@link CDOTransaction#commit()} is called.
+ * <p>
+ * Default value is 10000.
+ *
+ * @since 4.5
+ */
+ public long getCommitInfoTimeout();
+
+ /**
+ * Specifies the number of milliseconds to wait for the transaction update when {@link CDOTransaction#commit()} is called.
+ * <p>
+ * Default value is 10000.
+ *
+ * @since 4.5
+ */
+ public void setCommitInfoTimeout(long commitInfoTimeout);
+
+ /**
* An {@link IOptionsEvent options event} fired from transaction {@link CDOTransaction#options() options} when the
* {@link Options#setUndoDetector(CDOUndoDetector) undo detector} option has changed.
*
@@ -354,5 +377,18 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr
public interface AutoReleaseLocksEvent extends IOptionsEvent
{
}
+
+ /**
+ * An {@link IOptionsEvent options event} fired from transaction {@link CDOTransaction#options() options} when the
+ * {@link Options#setCommitInfoTimeout(long) commit info timeout} option has changed.
+ *
+ * @author Eike Stepper
+ * @since 4.5
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+ public interface CommitInfoTimeout extends IOptionsEvent
+ {
+ }
}
}
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 05654ab730..5643db22a1 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
@@ -1761,6 +1761,8 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl
private boolean terminateIfSessionClosed;
+ private int lastCommitNumber;
+
public Invalidator()
{
}
@@ -1772,15 +1774,12 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl
return null;
}
- final String threadName = Thread.currentThread().getName();
- Object token = new Object()
+ CommitToken token = new CommitToken(++lastCommitNumber, Thread.currentThread().getName());
+
+ if (DEBUG)
{
- @Override
- public String toString()
- {
- return threadName;
- }
- };
+ IOUtil.OUT().println(CDOSessionImpl.this + " [" + getLastUpdateTime() % 10000 + "] startLocalCommit: " + token);
+ }
unfinishedLocalCommits.add(token);
return token;
@@ -1788,6 +1787,11 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl
public synchronized void endLocalCommit(Object token)
{
+ if (DEBUG)
+ {
+ IOUtil.OUT().println(CDOSessionImpl.this + " [" + getLastUpdateTime() % 10000 + "] endLocalCommit: " + token);
+ }
+
unfinishedLocalCommits.remove(token);
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java
index 7170faedd9..d616a5ad11 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java
@@ -21,6 +21,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPointRange;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
@@ -396,6 +397,22 @@ public class DelegatingSessionProtocol extends Lifecycle implements CDOSessionPr
}
}
+ public CDOCommitInfo resetTransaction(int transactionID, int commitNumber)
+ {
+ int attempt = 0;
+ for (;;)
+ {
+ try
+ {
+ return delegate.resetTransaction(transactionID, commitNumber);
+ }
+ catch (Exception ex)
+ {
+ handleException(++attempt, ex);
+ }
+ }
+ }
+
public RepositoryTimeResult getRepositoryTime()
{
int attempt = 0;
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 bde1aa96ee..9aee7a2fd6 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
@@ -162,6 +162,7 @@ import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOSavepoint;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
+import org.eclipse.emf.spi.cdo.InternalCDOSession.CommitToken;
import org.eclipse.emf.spi.cdo.InternalCDOSession.MergeData;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
import org.eclipse.emf.spi.cdo.InternalCDOViewSet;
@@ -231,6 +232,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
private String commitComment;
+ private CommitToken commitToken;
+
// Bug 283985 (Re-attachment)
private final ThreadLocal<Boolean> providingCDOID = new InheritableThreadLocal<Boolean>()
{
@@ -1291,7 +1294,12 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
if (info != null)
{
long timeStamp = info.getTimeStamp();
- waitForUpdate(timeStamp, 10000);
+ long timeout = options().getCommitInfoTimeout();
+
+ if (!waitForUpdate(timeStamp, timeout))
+ {
+ throw new TimeoutRuntimeException("Did not receive an update: " + this);
+ }
}
return info;
@@ -1300,7 +1308,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
private synchronized CDOCommitInfo commitSynced(IProgressMonitor progressMonitor)
throws DanglingIntegrityException, CommitException
{
- Object token = null;
+ InternalCDOSession session = getSession();
try
{
@@ -1310,7 +1318,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
throw new LocalCommitConflictException(Messages.getString("CDOTransactionImpl.2")); //$NON-NLS-1$
}
- token = getSession().startLocalCommit();
+ commitToken = (CommitToken)session.startLocalCommit();
CDOTransactionStrategy transactionStrategy = getTransactionStrategy();
CDOCommitInfo info = transactionStrategy.commit(this, progressMonitor);
@@ -1331,21 +1339,53 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
catch (Throwable t)
{
- if (t.getCause() instanceof MonitorCanceledException
- && !(t.getCause().getCause() instanceof TimeoutRuntimeException))
+ try
+ {
+ // The commit may have succeeded on the server, but after that fact network problems or timeouts have hit us.
+ // Let's see if we can recover...
+ CDOCommitInfo info = session.getSessionProtocol().resetTransaction(getViewID(), commitToken.getCommitNumber());
+ if (info != null)
+ {
+ lastCommitTime = info.getTimeStamp();
+ session.invalidate(info, this, true, CDOProtocol.CommitNotificationInfo.IMPACT_NONE, null);
+
+ // At this point the session (invalidator) is recovered.
+ // Continue to rethrow the exception and let the client call rollback()...
+ }
+ }
+ catch (Throwable ex)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(ex);
+ }
+ }
+
+ Throwable cause = t.getCause();
+ if (cause instanceof MonitorCanceledException)
{
- throw new OperationCanceledException("CDOTransactionImpl.7");//$NON-NLS-1$
+ if (!(cause.getCause() instanceof TimeoutRuntimeException))
+ {
+ throw new OperationCanceledException("CDOTransactionImpl.7");//$NON-NLS-1$
+ }
}
throw new CommitException(t);
}
finally
{
- getSession().endLocalCommit(token);
+ session.endLocalCommit(commitToken);
+ commitToken = null;
+
clearResourcePathCacheIfNecessary(null);
}
}
+ public CommitToken getCommitToken()
+ {
+ return commitToken;
+ }
+
/**
* @since 2.0
*/
@@ -3529,6 +3569,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
private boolean autoReleaseLocksEnabled = true;
+ private long commitInfoTimeout = DEFAULT_COMMIT_INFO_TIMEOUT;
+
public OptionsImpl()
{
}
@@ -3710,6 +3752,28 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
fireEvent(event);
}
+ public long getCommitInfoTimeout()
+ {
+ return commitInfoTimeout;
+ }
+
+ public void setCommitInfoTimeout(long commitInfoTimeout)
+ {
+ checkActive();
+
+ IEvent event = null;
+ synchronized (CDOTransactionImpl.this)
+ {
+ if (this.commitInfoTimeout != commitInfoTimeout)
+ {
+ this.commitInfoTimeout = commitInfoTimeout;
+ event = new CommitInfoTimeoutImpl();
+ }
+ }
+
+ fireEvent(event);
+ }
+
/**
* @author Eike Stepper
*/
@@ -3761,5 +3825,18 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
super(OptionsImpl.this);
}
}
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class CommitInfoTimeoutImpl extends OptionsEvent implements CommitInfoTimeout
+ {
+ private static final long serialVersionUID = 1L;
+
+ public CommitInfoTimeoutImpl()
+ {
+ super(OptionsImpl.this);
+ }
+ }
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java
index 8ef89d8f25..ec58ab8fcd 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java
@@ -22,6 +22,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.branch.CDOBranchPointRange;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOID.ObjectType;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
@@ -257,6 +258,11 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo
*/
public CommitTransactionResult commitXATransactionCancel(InternalCDOXACommitContext xaContext, OMMonitor monitor);
+ /**
+ * @since 4.5
+ */
+ public CDOCommitInfo resetTransaction(int transactionID, int commitNumber);
+
public List<CDORemoteSession> getRemoteSessions(InternalCDORemoteSessionManager manager, boolean subscribe);
/**
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java
index 520369d4d2..5741976f2a 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java
@@ -312,6 +312,46 @@ public interface InternalCDOSession
boolean computeChangeSets);
/**
+ * @author Eike Stepper
+ * @since 4.5
+ */
+ public static final class CommitToken
+ {
+ private final int commitNumber;
+
+ private final String threadName;
+
+ public CommitToken(int commitNumber, String threadName)
+ {
+ this.commitNumber = commitNumber;
+ this.threadName = threadName;
+ }
+
+ public int getCommitNumber()
+ {
+ return commitNumber;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return commitNumber == ((CommitToken)obj).commitNumber;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return commitNumber;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "LocalCommit[" + getCommitNumber() + (threadName == null ? "" : ", " + threadName) + "]";
+ }
+ }
+
+ /**
* A data structure that holds all input and output values of {@link InternalCDOSession#getMergeData(CDOBranchPoint, CDOBranchPoint, CDOBranchPoint, boolean) InternalCDOSession.getMergeData()}.
*
* @author Eike Stepper
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java
index 9aa0854d64..49f6fd206d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java
@@ -30,6 +30,7 @@ import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult;
+import org.eclipse.emf.spi.cdo.InternalCDOSession.CommitToken;
import java.util.ArrayList;
import java.util.List;
@@ -48,6 +49,11 @@ public interface InternalCDOTransaction extends CDOTransaction, InternalCDOUserT
public InternalCDOCommitContext createCommitContext();
/**
+ * @since 4.5
+ */
+ public CommitToken getCommitToken();
+
+ /**
* @since 4.3
*/
public boolean hasMultipleSavepoints();

Back to the top