Apache Jackrabbit : Transactional model of the Microkernel based Jackrabbit prototype

The MicroKernel based JCR implementation uses snapshot isolation with a relaxed first committer wins [1] strategy. That is, on login each session is under the impression of operating on its own copy of the repository. Modifications from other sessions do not affect the current session. With the relaxed first committer wins strategy a later session will fail on save when it contains operations which are incompatible with the operations of an earlier session which saved successfully. This is different from the standard first committer wins strategy where failure would occur on conflicting operations rather than on incompatible operations. Incompatible is weaker than conflict since two write operation on the same item do conflict but are not incompatible. The details of what incompatible means are implemented in the MicroKernel's internal mergeNode method.

Snapshot isolation exhibits write skew [1] which might turn out to be problematic for maintaining consistency guarantees imposed by JCR. Consider the following events for node n which is initially of type nt:unstructured:

session1 = login()
session2 = login()                                                         

n1 = session1.getNode("n")
n1.setPrimaryType(nt:file)
n1.save()

n2 = session2.getNode("n")
n2.addNode("foo")
n2.save()

Both sessions will successfully complete since for each of them the consistency property (nt:file cannot have a child named "foo"). holds. The combined effect however will result in node n being of type nt:file and having a child node foo.

To avoid these kind of inconsistencies, the Microkernel needs to impose additional checks on transactions. A technique which avoids write skew effectively resulting in serializable histories is described in [2].

Another way to mitigate the problem is to add a constraint checking capability to the Microkernel. A client would include a specification of its constraint in the commit. The Microkernel would then determine whether that constraint would still hold after having processed the commit. If not the commit would simply fail. Note however, that this does not solve the problem for application constraints encoded in applications on top of the repository.

[1] A Critique of ANSI SQL Isolation Levels. Hal Berenson, Phil Bernstein, Jim Gray, Jim Melton, Elizabeth O'Neil, and Patrick O'Neil. June 1995

[2] Serializable isolation for snapshot databases. Michael J. Cahill, Uwe Röhm, and Alan D. Fekete. 2008.