This kind of scares me a bit: What could session3 possibly do about this here ?

It looks like session3 is created after everything is set and done, thus it is 
expected that p1==p2==-1 and thus p1-p2==0.

session3 can't do anything about it, session 2 could. See [1]. This is a consequence inherent to snapshot isolation.

[1] http://dl.acm.org/citation.cfm?id=1376690



Regards
Felix

Am 30.11.2011 um 13:38 schrieb Michael Dürig:


Hi,

As documented earlier [1] new Mircokernel based JCR implementations will
most likely introduce snapshot isolation for sessions. While I think
this is a good thing in general, it also introduces potentially
troublesome write skew: application level constraints might hold locally
(i.e. per session) but might fail globally. That is, in order to enforce
some constraints, applications might need to implement explicit cross
session synchronization mechanisms instead of being able to rely on
session isolation. The following test case demonstrates the issue.

/**
  * 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.
  */
@Test
public void testSessionIsolation() throws RepositoryException {
     Repository repository = getRepository();

     Session session0 = repository.login();
     Node testNode = session0.getNode("/").addNode("testNode");
     testNode.setProperty("p1", 1);
     testNode.setProperty("p2", 1);
     session0.save();
     check(getSession());

     Session session1 = repository.login();
     Session session2 = repository.login();

     session1.getNode("/testNode").setProperty("p1", -1);
     check(session1);
     session1.save();

     session2.getNode("/testNode").setProperty("p2", -1);
     check(session2);  // Throws on JR2 but not on JR3
     session2.save();

     Session session3 = repository.login();
     check(session3);  // Throws on JR3
}

private static void check(Session session) throws RepositoryException {
     if (session.getNode("/testNode").getProperty("p1").getLong() +
         session.getNode("/testNode").getProperty("p2").getLong()<  0) {
           fail("p1 + p2<  0");
   }
}

Michael

[1]
http://wiki.apache.org/jackrabbit/Transactional%20model%20of%20the%20Microkernel%20based%20Jackrabbit%20prototype

Reply via email to