2
votes

I'm doing an academic research in trying to develop a programming tool that assists in implementing fine-grained locking functions, for concurrent programs that maintain tree-like data structures.

For example, the programmer may write some functions that receive a tree root-node and modify the tree (by traversing on some routes and adding/removing nodes), and the tool will help him to find where in the code nodes should be locked and where they can be released - so the functions could be executed concurrently on the same tree.

I am looking for some real-life code examples in which such fine-grained locking is used, or where it could be used for better performance but the programmer was too lazy to implement it (for example, he locked the whole tree during the function-call without releasing useless nodes).

I read about JCR & Jackrabbit, which use a tree-shaped database, and found an article that explains how to lock nodes in JCR (but without examples): http://www.day.com/specs/jcr/2.0/17_Locking.html

I have a really small background in databases, and I don't fully understand what is allowed and what is not allowed when it comes to Jackrabbit databases and concurrency. Accessing the same node from 2 threads is not allowed, but what about different repositories? And what happens if 2 different clients try to access the same node (for example, one tries to delete it, and another one tries to modify it - will the session.save() fail?).

Thanks, Oren

1
You might also inquire at the Adobe forums for CQ5 (forums.adobe.com/community/digital_marketing_suite/cq5). CQ5's implementation of JCR, known as CRX, is a commercial version of Apache Jackrabbit.David Gorsline
You want to stay in the realm of JCR? Are you open to other technologies?David J.
The Clojure community thinks a lot about concurrency, that was one of its drivers. See clojure.org/concurrent_programming -- and in many cases suggests that, in practice, programmers make better programs when they don't explicitly use locks. That's why Clojure offers approaches that are considerably different than traditional Java locking. If you are open to this, we can find plenty of Clojure code examples.David J.

1 Answers

2
votes

First of all, don't get confused between databases/jackrabbit/locking. Jackrabbit implements its own locking, as do databases.

Jackrabbit allows you to lock nodes using LockManager.lock(). Setting the isDeep parameter to true means all the nodes underneath will also be locked. A locked node can be read by another session but can't be modified.

Technically speaking, 2 threads COULD edit the same node if they are using the same session but this is rather hazardous and should probably be avoided.

If a node is likely to be modified by 2 concurrent sessions then you should always lock the node. Which ever session gets there last should wait for the lock to be released. If you don't lock then at least one of the sessions will throw an exception.

I'm not sure what you mean by accessing nodes from different repositories. A node can only belong to one repository. If you mean having 2 jackrabbit instances accessing the same database then this too should be avoided or you should look to using clustering.

When implementing locking it is going to depend on your design and requirements. There's no point locking if you'll only ever have one session and vice-versa. Whether you lock a node or sub-tree is going to depend on what your data represents. For example, if a node represents a folder you'll probably want to lock just the node and not the whole sub-tree. If a sub-tree represents a complex document then you probably will want to lock the sub-tree.

As for locking the whole tree, I hope I don't meet someone who does that!