You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2014/04/02 18:03:53 UTC
svn commit: r1584076 -
/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CompatibilityIssuesTest.java
Author: mduerig
Date: Wed Apr 2 16:03:53 2014
New Revision: 1584076
URL: http://svn.apache.org/r1584076
Log:
OAK-26: MVCC causes write skew
Put write skew test back, which go lost somewhere on the way
Modified:
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CompatibilityIssuesTest.java
Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CompatibilityIssuesTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CompatibilityIssuesTest.java?rev=1584076&r1=1584075&r2=1584076&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CompatibilityIssuesTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CompatibilityIssuesTest.java Wed Apr 2 16:03:53 2014
@@ -31,7 +31,10 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import javax.jcr.Credentials;
@@ -87,6 +90,83 @@ public class CompatibilityIssuesTest ext
super(fixture);
}
+ /**
+ * Trans-session isolation differs from Jackrabbit 2. Snapshot isolation can
+ * result in write skew as this test demonstrates: the check method enforces
+ * an application logic constraint which says that the sum of the properties
+ * p1 and p2 must not be negative. While session1 and session2 each enforce
+ * this constraint before saving, the constraint might not hold globally as
+ * can be seen in session3.
+ *
+ * @see <a href="http://wiki.apache.org/jackrabbit/Transactional%20model%20of%20the%20Microkernel%20based%20Jackrabbit%20prototype">
+ * Transactional model of the Microkernel based Jackrabbit prototype</a>
+ */
+ @Test
+ public void sessionIsolation() throws RepositoryException, ExecutionException, InterruptedException {
+ // Execute all operations in serial but on different threads to ensure
+ // same thread session refreshing doesn't come into the way
+ final Session session0 = createAdminSession();
+ try {
+ FutureTask<Void> t0 = new FutureTask<Void>(new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ Node testNode = session0.getNode("/").addNode("testNode");
+ testNode.setProperty("p1", 1);
+ testNode.setProperty("p2", 1);
+ session0.save();
+ check(getAdminSession());
+ return null;
+ }
+ });
+ new Thread(t0).start();
+ t0.get();
+ } finally {
+ session0.logout();
+ }
+
+ final Session session1 = createAdminSession();
+ final Session session2 = createAdminSession();
+ try {
+ FutureTask<Void> t1 = new FutureTask<Void>(new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ session1.getNode("/testNode").setProperty("p1", -1);
+ check(session1);
+ session1.save();
+ return null;
+ }
+ });
+ new Thread(t1).start();
+ t1.get();
+
+ FutureTask<Void> t2 = new FutureTask<Void>(new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ session2.getNode("/testNode").setProperty("p2", -1);
+ check(session2); // Throws on JR2, not on Oak
+ session2.save();
+ return null;
+ }
+ });
+ new Thread(t2).start();
+ t2.get();
+
+ } finally {
+ session1.logout();
+ session2.logout();
+ }
+
+ Session session3 = createAnonymousSession();
+ try {
+ check(session3); // Throws on Oak
+ fail();
+ } catch (AssertionError e) {
+ // expected
+ } finally {
+ session3.logout();
+ }
+ }
+
private static void check(Session session) throws RepositoryException {
if (session.getNode("/testNode").getProperty("p1").getLong() +
session.getNode("/testNode").getProperty("p2").getLong() < 0) {