Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2013-05-31 23:49:20 -0400
committerEike Stepper2013-06-01 03:16:38 -0400
commit7fea1d39bc661b593b16bb6ccdcaf3ba67459c87 (patch)
treef1f60195410fc695babc9b121dd4673310e305b8
parenta5807c7e51c49f4823d2514679a98d4136273902 (diff)
downloadcdo-7fea1d39bc661b593b16bb6ccdcaf3ba67459c87.tar.gz
cdo-7fea1d39bc661b593b16bb6ccdcaf3ba67459c87.tar.xz
cdo-7fea1d39bc661b593b16bb6ccdcaf3ba67459c87.zip
[409574] Provide a meaningful CommitException hierarchy
https://bugs.eclipse.org/bugs/show_bug.cgi?id=409574
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOAutoLocker.java53
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUserTransaction.java61
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitConflictException.java17
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitException.java41
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitIntegrityException.java4
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ConcurrentAccessException.java14
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ContainmentCycleException.java11
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DanglingIntegrityException.java8
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DataIntegrityException.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ImplicitLockingException.java27
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/LocalCommitConflictException.java14
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/OptimisticLockingException.java41
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ReferentialIntegrityException.java17
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java6
16 files changed, 278 insertions, 49 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 ee540b9266..ee296f172e 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
@@ -340,6 +340,9 @@ public interface CDOProtocolConstants
*/
public static final byte REPLICATE_LOCKAREA = 3;
+ // //////////////////////////////////////////////////////////////////////
+ // Committing Transactions
+
/**
* @since 4.2
*/
@@ -348,7 +351,7 @@ public interface CDOProtocolConstants
/**
* @since 4.2
*/
- public static final byte ROLLBACK_REASON_IMPLICIT_LOCKING = 1;
+ public static final byte ROLLBACK_REASON_OPTIMISTIC_LOCKING = 1;
/**
* @since 4.2
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 bd58ea85cb..6dbe4b310f 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
@@ -933,7 +933,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
catch (Exception ex)
{
- throw new RollbackException(CDOProtocolConstants.ROLLBACK_REASON_IMPLICIT_LOCKING, ex);
+ throw new RollbackException(CDOProtocolConstants.ROLLBACK_REASON_OPTIMISTIC_LOCKING, ex);
}
// If all locks could be acquired, check if locked targets do still exist
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOAutoLocker.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOAutoLocker.java
new file mode 100644
index 0000000000..bfe53db970
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOAutoLocker.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.transaction;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+
+import org.eclipse.net4j.util.WrappedException;
+
+import java.util.concurrent.TimeoutException;
+
+/**
+ * A {@link CDOTransactionHandler1 transaction handler} that automatically acquires {@link CDOObject#cdoWriteLock() write locks} when
+ * {@link CDOObject objects} are modified.
+ *
+ * @author Eike Stepper
+ * @since 4.2
+ */
+public class CDOAutoLocker extends CDODefaultTransactionHandler1
+{
+ private long timeout;
+
+ public CDOAutoLocker(long timeout)
+ {
+ this.timeout = timeout;
+ }
+
+ public CDOAutoLocker()
+ {
+ this(10000);
+ }
+
+ @Override
+ public void modifyingObject(CDOTransaction transaction, CDOObject object, CDOFeatureDelta featureChange)
+ {
+ try
+ {
+ object.cdoWriteLock().lock(timeout);
+ }
+ catch (TimeoutException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUserTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUserTransaction.java
index 3fe0d4b3af..95f2f4cfe7 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUserTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUserTransaction.java
@@ -11,15 +11,18 @@
*/
package org.eclipse.emf.cdo.transaction;
+import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.util.CommitException;
+import org.eclipse.emf.cdo.util.ConcurrentAccessException;
+import org.eclipse.emf.cdo.util.ContainmentCycleException;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* Provides functionality that is common to both {@link CDOTransaction single} transactions and {@link CDOXATransaction
* distributed} (XA) transactions.
- *
+ *
* @author Simon McDuff
* @since 2.0
* @noextend This interface is not intended to be extended by clients.
@@ -28,14 +31,64 @@ import org.eclipse.core.runtime.IProgressMonitor;
public interface CDOUserTransaction
{
/**
+ * Same as {@link #commit(IProgressMonitor) commit(null)}.
+ *
* @since 3.0
*/
- public CDOCommitInfo commit() throws CommitException;
+ public CDOCommitInfo commit() throws ConcurrentAccessException, CommitException;
/**
+ * Commits the modifications of this transaction to the repository and returns a {@link CDOCommitInfo commit info} object if successful.
+ * <p>
+ * Various kinds of problems <b>can</b> cause the commit to fail and not all of them can be avoided by acquiring pessimistic {@link CDOObject#cdoWriteLock() locks}
+ * on the modified objects. In particular you <b>must</b> expect and handle {@link ContainmentCycleException containment cycle exceptions}. The following example shows how
+ * write robust transactions:
+ * <pre>
+ CDOTransaction transaction = null;
+
+ try
+ {
+ transaction = session.openTransaction();
+
+ for (;;)
+ {
+ try
+ {
+ synchronized (transaction)
+ {
+ CDOResource resource = transaction.getResource("/stock/resource1");
+
+ // Modify the model here...
+
+ transaction.commit();
+ break;
+ }
+ }
+ catch (ConcurrentAccessException ex)
+ {
+ transaction.rollback();
+ }
+ catch (CommitException ex)
+ {
+ throw ex.wrap();
+ }
+ }
+ }
+ finally
+ {
+ if (transaction != null)
+ {
+ transaction.close();
+ }
+ }
+ * </pre>
+ *
+ * Note that the transaction stays functional after a any call to the <code>commit()</code> methods. If the transaction is not closed after a commit
+ * it can be used to apply additional modifications to the model.
+ *
* @since 3.0
*/
- public CDOCommitInfo commit(IProgressMonitor progressMonitor) throws CommitException;
+ public CDOCommitInfo commit(IProgressMonitor progressMonitor) throws ConcurrentAccessException, CommitException;
public void rollback();
@@ -44,7 +97,7 @@ public interface CDOUserTransaction
* <p>
* Save points do not involve the server side, everything is done on the client side.
* <p>
- *
+ *
* @since 3.0
*/
public CDOUserSavepoint setSavepoint();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitConflictException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitConflictException.java
index 3b33842483..e76bbc7b47 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitConflictException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitConflictException.java
@@ -10,7 +10,24 @@
*/
package org.eclipse.emf.cdo.util;
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.transaction.CDOAutoLocker;
+import org.eclipse.emf.cdo.transaction.CDOConflictResolver;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
/**
+ * A {@link ConcurrentAccessException concurrent access exception} that indicates that some of the local modifications are based on old revisions
+ * because other transactions have intermittently committed their modifications.
+ * <p>
+ * It's usually possible and adequate to {@link CDOTransaction#rollback() rollback} the transaction, <i>replay</i> the model modifications and
+ * commit the transaction again (optimistic strategy). Pessimistic {@link CDOObject#cdoWriteLock() locks} can help to avoid the problematic situation
+ * (see also {@link CDOAutoLocker}).
+ * <p>
+ * Instances of this class indicate commit conflicts that are detected in the repository. They can also occur if a {@link CDOConflictResolver conflict resolver}
+ * is used locally (network race condition).
+ * <p>
+ * For detection of local commit conflicts see {@link LocalCommitConflictException}.
+ *
* @author Eike Stepper
* @since 4.2
* @noextend This interface is not intended to be extended by clients.
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitException.java
index ed1fc428fa..000a71e999 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitException.java
@@ -12,9 +12,42 @@ package org.eclipse.emf.cdo.util;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.net4j.util.transaction.TransactionException;
+
/**
- * A checked exception being thrown from {@link CDOTransaction#commit()} in case of unrecoverable commit problems such
- * as commit conflicts.
+ * A checked exception being thrown from {@link CDOTransaction#commit()} in case of commit problems such as commit conflicts.
+ * <p>
+ * This class is the root of an exception hierarchy that allows to determine and handle specific causes of commit problems:
+ *
+ * <pre>
+ CDOTransaction transaction = session.openTransaction();
+
+ for (;;)
+ {
+ try
+ {
+ synchronized (transaction)
+ {
+ CDOResource resource = transaction.getResource("/stock/resource1");
+
+ // Modify the model here...
+
+ transaction.commit();
+ break;
+ }
+ }
+ catch (ConcurrentAccessException ex)
+ {
+ transaction.rollback();
+ }
+ catch (CommitException ex)
+ {
+ throw ex.wrap();
+ }
+ }
+ * </pre>
+ *
+ * Instances of this class indicate low-level technical problems such as database or network issues.
*
* @author Eike Stepper
* @since 3.0
@@ -55,8 +88,8 @@ public class CommitException extends Exception
/**
* @since 4.2
*/
- public boolean isFatal()
+ public TransactionException wrap()
{
- return true;
+ return new TransactionException(this);
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitIntegrityException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitIntegrityException.java
index 121398a9d8..cc6ebea95f 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitIntegrityException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CommitIntegrityException.java
@@ -17,8 +17,8 @@ import org.eclipse.emf.ecore.EObject;
import java.util.Set;
/**
- * A {@link CommitException commit exception} that indicates referential integrity problems with
- * {@link CDOTransaction#setCommittables(Set) partial commits} before the server is contacted.
+ * A local {@link DataIntegrityException data integrity exception} that indicates that the subset of object modifications in a
+ * {@link CDOTransaction#setCommittables(Set) partial commit} is inconsistent.
*
* @author Caspar De Groot
* @since 4.0
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ConcurrentAccessException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ConcurrentAccessException.java
index c6cc6e767e..a23dd2f568 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ConcurrentAccessException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ConcurrentAccessException.java
@@ -10,7 +10,15 @@
*/
package org.eclipse.emf.cdo.util;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
/**
+ * A {@link CommitException commit exception} that indicates problems that are caused by concurrent access to the repository.
+ * <p>
+ * Subtypes of this exception allow to determine a more specific reason for the problem. They all have in common that it's usually
+ * possible and adequate to {@link CDOTransaction#rollback() rollback} the transaction, <i>replay</i> the model modifications and
+ * commit the transaction again.
+ *
* @author Eike Stepper
* @since 4.2
* @noextend This interface is not intended to be extended by clients.
@@ -38,10 +46,4 @@ public class ConcurrentAccessException extends CommitException
{
super(cause);
}
-
- @Override
- public boolean isFatal()
- {
- return false;
- }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ContainmentCycleException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ContainmentCycleException.java
index efbb388258..3bd95591ad 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ContainmentCycleException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ContainmentCycleException.java
@@ -10,7 +10,18 @@
*/
package org.eclipse.emf.cdo.util;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
/**
+ * A {@link ConcurrentAccessException concurrent access exception} that indicates an attempt of the local transaction to introduce a <i>containment cycle</i>.
+ * A containment cycle is an effect of a network race condition between two transactions that commit changes to possibly disjunct sets of objects. As a result
+ * the overall tree structure of the model would be destroyed in a way that the tree root would no longer be reachable from objects involved in the containment cycle.
+ * Commits that attempt to introduce containment cycles are detected by the repository and canceled. Note that locking all involved <b>dirty</b> objects
+ * does not properly address the problem because the involved container objects may not be dirty.
+ * <p>
+ * It's usually possible and adequate to {@link CDOTransaction#rollback() rollback} the transaction, <i>replay</i> the model modifications and
+ * commit the transaction again (optimistic strategy). Pessimistic locks on the dirty objects can not safely avoid the problem; you must expect this exception to occur.
+ *
* @author Eike Stepper
* @since 4.2
* @noextend This interface is not intended to be extended by clients.
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DanglingIntegrityException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DanglingIntegrityException.java
index 2f10f9d3c7..310b9c7e41 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DanglingIntegrityException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DanglingIntegrityException.java
@@ -11,9 +11,17 @@
*/
package org.eclipse.emf.cdo.util;
+import org.eclipse.emf.cdo.transaction.CDOAutoAttacher;
+
import org.eclipse.emf.ecore.EObject;
/**
+ * A local {@link DataIntegrityException data integrity exception} that indicates the addition of one or more cross references to objects
+ * that are not (or no longer) contained in the repository.
+ * <p>
+ * The target objects of the respective dangling references must be attached to the repository.
+ * A {@link CDOAutoAttacher} can help to do so.
+ *
* @author Eike Stepper
* @since 4.2
* @noextend This interface is not intended to be extended by clients.
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DataIntegrityException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DataIntegrityException.java
index 4977b32d5c..6c22079afa 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DataIntegrityException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/DataIntegrityException.java
@@ -10,8 +10,14 @@
*/
package org.eclipse.emf.cdo.util;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
/**
+ * A {@link CommitException commit exception} that indicates data integrity problems.
+ * <p>
+ * Subtypes of this exception allow to determine a more specific reason for the problem. They all have in common that it's usually
+ * <b>not</b> adequate to {@link CDOTransaction#rollback() rollback} the transaction, <i>replay</i> the model modifications and commit the transaction again.
+ *
* @author Eike Stepper
* @since 4.2
* @noextend This interface is not intended to be extended by clients.
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ImplicitLockingException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ImplicitLockingException.java
deleted file mode 100644
index 541b5e7f5c..0000000000
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ImplicitLockingException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2004-2013 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.util;
-
-/**
- * @author Eike Stepper
- * @since 4.2
- * @noextend This interface is not intended to be extended by clients.
- * @noinstantiate This class is not intended to be instantiated by clients.
- */
-public class ImplicitLockingException extends ConcurrentAccessException
-{
- private static final long serialVersionUID = 1L;
-
- public ImplicitLockingException(String message)
- {
- super(message);
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/LocalCommitConflictException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/LocalCommitConflictException.java
index 5034a36d9a..ca794595d7 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/LocalCommitConflictException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/LocalCommitConflictException.java
@@ -10,7 +10,21 @@
*/
package org.eclipse.emf.cdo.util;
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.transaction.CDOAutoLocker;
+import org.eclipse.emf.cdo.transaction.CDOConflictResolver;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
/**
+ * A {@link CommitConflictException commit conflict exception} that indicates that the transaction has local {@link CDOTransaction#hasConflict() conflicts}.
+ * <p>
+ * It's usually possible and adequate to {@link CDOTransaction#rollback() rollback} the transaction, <i>replay</i> the model modifications and
+ * commit the transaction again (optimistic strategy). Pessimistic {@link CDOObject#cdoWriteLock() locks} can help to avoid the problematic situation
+ * (see also {@link CDOAutoLocker}).
+ * <p>
+ * Instances of this class indicate commit conflicts that are detected locally by analyzing the {@link org.eclipse.emf.cdo.session.CDOSession.Options#setPassiveUpdateEnabled(boolean) passive updates}
+ * that result from commits of other transactions. {@link CDOConflictResolver Conflict resolvers} can help to reduce the risk of local commit conflicts.
+ *
* @author Eike Stepper
* @since 4.2
* @noextend This interface is not intended to be extended by clients.
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/OptimisticLockingException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/OptimisticLockingException.java
new file mode 100644
index 0000000000..fcf9d2c0a7
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/OptimisticLockingException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2004-2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.util;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.transaction.CDOAutoLocker;
+
+/**
+ * A {@link ConcurrentAccessException concurrent access exception} that indicates that the repository can not acquire optimistic locks for some of the locally modified objects.
+ * <p>
+ * It's usually possible and adequate to attempt to commit the transaction again (optimistic strategy).
+ * Pessimistic {@link CDOObject#cdoWriteLock() locks} can help to avoid the problematic situation (see also {@link CDOAutoLocker}) at commit time.
+ * <p>
+ * The optimistic locking timeout can be configured on the server side:
+ *
+ * <pre>
+ &lt;property name="optimisticLockingTimeout" value="10000"/>
+ * </pre>
+ *
+ * @author Eike Stepper
+ * @since 4.2
+ * @noextend This interface is not intended to be extended by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class OptimisticLockingException extends ConcurrentAccessException
+{
+ private static final long serialVersionUID = 1L;
+
+ public OptimisticLockingException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ReferentialIntegrityException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ReferentialIntegrityException.java
index b8ae2e2fcb..dea7c7c342 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ReferentialIntegrityException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ReferentialIntegrityException.java
@@ -11,11 +11,26 @@
package org.eclipse.emf.cdo.util;
import org.eclipse.emf.cdo.CDOObjectReference;
+import org.eclipse.emf.cdo.view.CDOView;
import java.util.List;
/**
- * A {@link CommitException commit exception} that indicates referential integrity problems detected by the server.
+ * A {@link DataIntegrityException data integrity exception} that indicates an attempt to create <i>stale references</i>.
+ * A stale reference is a refenrence that points to a target object that does not (or no longer) exist.
+ * <p>
+ * Detection of referential integrity violations must be explicitely enabled on the server side because it can be expensive:
+ *
+ * <pre>
+ &lt;property name="ensureReferentialIntegrity" value="true"/>
+ * </pre>
+ * The risk of referential integrity violations can be <b>reduced</b> (but not eliminated) by using local cross reference queries
+ * before committing:
+ * <p>
+ * <ul>
+ * <li> {@link CDOView#queryXRefs(org.eclipse.emf.cdo.CDOObject, org.eclipse.emf.ecore.EReference...) CDOView#queryXRefs()}
+ * <li> {@link CDOView#queryXRefsAsync(java.util.Set, org.eclipse.emf.ecore.EReference...) CDOView#queryXRefsAsync()}
+ * </ul>
*
* @author Eike Stepper
* @since 4.0
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java
index be434cc9a2..27aae95a0b 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java
@@ -18,7 +18,7 @@ import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
import org.eclipse.emf.cdo.util.CommitConflictException;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.util.ContainmentCycleException;
-import org.eclipse.emf.cdo.util.ImplicitLockingException;
+import org.eclipse.emf.cdo.util.OptimisticLockingException;
import org.eclipse.emf.cdo.util.ReferentialIntegrityException;
import org.eclipse.emf.internal.cdo.bundle.OM;
@@ -79,8 +79,8 @@ public class CDOSingleTransactionStrategyImpl implements CDOTransactionStrategy
byte rollbackReason = result.getRollbackReason();
switch (rollbackReason)
{
- case CDOProtocolConstants.ROLLBACK_REASON_IMPLICIT_LOCKING:
- throw new ImplicitLockingException(rollbackMessage);
+ case CDOProtocolConstants.ROLLBACK_REASON_OPTIMISTIC_LOCKING:
+ throw new OptimisticLockingException(rollbackMessage);
case CDOProtocolConstants.ROLLBACK_REASON_COMMIT_CONFLICT:
throw new CommitConflictException(rollbackMessage);

Back to the top