Hello,

I have written a test-method that deals with the behavior of xa transactions and can be executed within XATest.java ( http://svn.apache.org/repos/asf/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/XATest.java ) - it is attached below this email. The test-method attempts to simulate the case that two transactions edit the same property of a node concurrently. It fails with a RollbackException once the second transaction commits (at the latest if the test-method is executed more than once). The very first question is: Is it a valid approach to simulate two concurrent transactions like that within XATest? :) If so, then there are more questions: Does this test-method show the intended behavior? That would imply some kind of a prevention of lost updates. If that is not the intended behavior: What is wrong or what am I doing wrong?

I'm doubtful that the test-method shows the intended behavior, because: 1) I have already suggested above that the test-method sometimes passes. 2.) If I change the passage of code below the 'prerequisite'-comment into (so that the 'testNode' is 'fresh' each time)

            // prerequisite for test - fresh 'testNode' exists
            if (session0.getRootNode().hasNode("testNode")) {
                session0.getRootNode().getNode("testNode").remove();
                session0.save();
            }
            session0.getRootNode().addNode("testNode");
            session0.save();

then the test-method never fails.
However, I am confused. Especially since the test seems to always fail if I map it onto a scenario that uses the JCA package and container managed transactions. In a nutshell, what I would like to know is: What is the *intended* behavior?

Many thanks,
Dominik


public void testConcurrentTx() throws Exception {
        Session session0 = null;
        Session session1 = null;
        Session session2 = null;
        try {
            session0 = getHelper().getSuperuserSession();
            session1 = getHelper().getSuperuserSession();
            session2 = getHelper().getSuperuserSession();

            // prerequisite for test - 'testNode' exists
            if (!session0.getRootNode().hasNode("testNode")) {
                session0.getRootNode().addNode("testNode");
                session0.save();
            }

// two concurrent transactions, which both set a property of the 'testNode' and then commit
            UserTransaction utx1 = new UserTransactionImpl(session1);
            UserTransaction utx2 = new UserTransactionImpl(session2);

            utx1.begin();
            utx2.begin();

session1.getRootNode().getNode("testNode").setProperty("test", "session1");
            session1.save();

session2.getRootNode().getNode("testNode").setProperty("test", "session2");
            session2.save();

            utx1.commit();
            utx2.commit();

        } finally {
            if (session0 != null) {
                session0.logout();
            }
            if (session1 != null) {
                session1.logout();
            }
            if (session2 != null) {
                session2.logout();
            }
        }
    }

Reply via email to