vijay s wrote:
Problem:

I am able to get my application working with the Locked utility class, but I
believe the locking of the folder to add content is causing some issues when
I try to "concurrently" add many nodes to a single folder.
Jackrabbit throws a random ItemNotFoundException after I add about 400 nodes
concurrently in 20 threads --> (javax.jcr.ItemNotFoundException: a3214cbe-2a89-4550-8b1b-2b76cce821c0/{http://www.jcp.org/jcr/1.0}lockOwner).
Once such an error happens in one of my threads, the rest of the threads get
stuck in some form of a deadlock and my server crashes. The crashes become
more frequent and detrimental as I increase the number of concurrent threds.

this is strange. our test cases for the utility use 100 concurrent threads and run without any errors. See: http://svn.apache.org/repos/asf/jackrabbit/tags/1.2.1/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/LockTest.java

Questions:

1) Is there any alternative to this locking procedure to add child nodes to
a node. Do we "have" to lock a parent node to add child nodes ?

No, as of version 1.2.1 jackrabbit is able to handle concurrent addNode() from multiple sessions without the need to lock the parent node. See: http://issues.apache.org/jira/browse/JCR-584

I have found
that I get better reliability when I do not use the Locked utility class,
but just synchronize the code in a way where only one session can add nodes
to a particular folder. I really do not want to single thread the
application. Any recommendations on a better approach will be really
appreciated. Any insights on this particular cause of the
ItemNotFoundException will also be helpful.

See my comments inline

Code Snippet:

        public void addContent(final String nodeId, final String nodeType, final
Map properties) {
                System.out.println("Adding project "+nodeId);

Where do you get the session from? What does the parameter do?

                Session session = getSession(true);
                try {
                        final Node folder = 
session.getRootNode().getNode("assemblies");
                        Node child = null;
                        if (!folder.hasNode(nodeId)) {
                                Object retChild = new Locked() {
                                     protected Object run(Node folder) throws 
RepositoryException {
                                         Node c = folder.addNode(nodeId, 
nodeType != null ? nodeType
                                                                        : 
"nt:unstructured");
                                                        
c.addMixin("mix:versionable");
                                                        for (Object key : 
properties.keySet()) {
                                                                
c.setProperty((String) key, (String) properties
                                                                                
.get(key));
} folder.save();
                                         return c;
                                     }
                                }.with(folder, false,100000);
                                if(retChild==Locked.TIMED_OUT){
                                        throw new RuntimeException("Exception 
occured when adding a node.
Please try again");
                                } else {
                                        child = (Node)retChild;
                                }

This call is not needed. There shouldn't be any changes on the session at this point.

                                session.save();
                                child = folder.getNode(nodeId);
                                System.out.println("Added project 
"+child.getPath()+" successfully");
                        }
                } catch (InterruptedException ex) {
                        throw new RuntimeException(ex);                 
                } catch (RepositoryException ex) {
                        throw convertJCRAccessException(ex);
                } finally {                     
                        session.logout();
                }
        }

Otherwise the code looks ok to me.

Are you able to get the stacktrace of the root cause? The one that shows where the ItemNotFoundException is thrown.

regards
 marcel

Exception Snippet:
org.springframework.dao.DataRetrievalFailureException: Item not found;
nested exception is javax.jcr.ItemNotFoundException:
a3214cbe-2a89-4550-8b1b-2b76cce821c0/{http://www.jcp.org/jcr/1.0}lockOwner
        at
org.springmodules.jcr.SessionFactoryUtils.translateException(SessionFactoryUtils.java:197)
        at
org.springmodules.jcr.JcrAccessor.convertJcrAccessException(JcrAccessor.java:58)
        at
org.springmodules.jcr.support.JcrDaoSupport.convertJCRAccessException(JcrDaoSupport.java:117)
        at ContentDaoImpl.addContent(ContentDaoImpl.java:44)
        at ContentServiceImpl.addNewProject(ContentServiceImpl.java:51)


Reply via email to