jackrabbit-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dominik Klaholt <do...@mail.upb.de>
Subject Re: Jackrabbit, JCA, JBoss, EJB and transactions
Date Fri, 06 Aug 2010 14:38:05 GMT
I have simplified the test-case that shows the - in my opinion - 
questionalbe behavior. Now it's without the confusing EJB stuff - just 
Jackrabbit and transactions. Any thoughts?

         /**
          * The following test-case works, IF step 1 is done without 
being encapsulated in a transaction (just remove the
          * utx-lines in step 1 and add the 's1.logout()')
          */
         String id;
         InitialContext jndiContext = new InitialContext();
         rep = (Repository) jndiContext.lookup("java:/jcr/local");

         // Step 1: user 1 acquires session and writes, then logs out
         utx = (UserTransaction) jndiContext.lookup("UserTransaction");
         utx.begin();
         Session s1 = rep.login(new SimpleCredentials(USER1, 
USER1.toCharArray()));
         Node nodeBys1 = s1.getRootNode().addNode("aNode");
         nodeBys1.setProperty("aProperty", USER1);
         s1.save();
         id = nodeBys1.getIdentifier();
         // s1.logout();
         utx.commit();

         // Step 2: user 2 acquires session, alters value written by 
user 1, then logs out
         utx = (UserTransaction) jndiContext.lookup("UserTransaction");
         utx.begin();
         Session s2 = rep.login(new SimpleCredentials(USER2, 
USER2.toCharArray()));
         s2.getNodeByIdentifier(id).setProperty("aProperty", USER2);
         s2.save();
         utx.commit();

         // Step 3: user 1 acquires session again, reads the property 
altered by user 2... but does not read the correct
         // value
         utx = (UserTransaction) jndiContext.lookup("UserTransaction");
         utx.begin();
         Session s = rep.login(new SimpleCredentials(USER1, 
USER1.toCharArray()));
         AssertJUnit.assertEquals(USER2, 
s.getNodeByIdentifier(id).getProperty("aProperty").getString());
         utx.commit();


Am 06.08.2010 02:19, schrieb Dominik Klaholt:
> Hello,
>
> i have a problem using jackrabbit with EJB transactions. I will try to 
> explain what i have done and understood so far. Any corrections are 
> really welcome.
> I am using Jackrabbit 2.1.0 within JBoss 5.1.0 as a XA-datasource by 
> help of the JCA adapter that is provided by Jackrabbit. My jcr-ds.xml 
> contains the flags
>
> <config-property name="bindSessionToTransaction" 
> type="java.lang.Boolean">true</config-property>
>
> and
>
> <application-managed-security/>
>
> so that the JCA-session-handles are bound to the container/bean 
> managed transactions and the actual JCR sessions within the JCA 
> connection pool are
> distinguished by the parameters of the 'repository.login()' calls.
>
> The following test-case works fine:
>
> (1)Repository rep = (Repository) jndiContext.lookup("java:/jcr/local");
>     Session s1 = rep.login(new SimpleCredentials(USER1, 
> USER1.toCharArray()));
>     Node nodeBys1 = s1.getRootNode().addNode("aNode");
>     nodeBys1.setProperty("aProperty", USER1);
>     s1.save();
>     String id = nodeBys1.getIdentifier();
>     s1.logout();
>
> (2)Session s2 = rep.login(new SimpleCredentials(USER2, 
> USER2.toCharArray()));
>     s2.getNodeByIdentifier(id).setProperty("aProperty", USER2);
>     s2.save();
>     s2.logout();
>
> (3)Session s1 = rep.login(new SimpleCredentials(USER1, 
> USER1.toCharArray()));
>     AssertJUnit.assertEquals(USER2, 
> s1.getNodeByIdentifier(id).getProperty("aProperty").getString());
>
> (1) User 1 logs in and creates a node with a property. (2) Then user 2 
> logs in and alters the property of the
> newly created node. (3) Finally user 1 logs in again and reads the 
> property. He reads the value user 2 has written.
>
> Now, i want to encapsulate each of these three steps in one method of 
> a Stateless Session Bean. E.g. (1) looks like this:
>
>     public String createNode(String username) throws Exception {
>         InitialContext jndiContext = new InitialContext();
>         Repository rep = (Repository) 
> jndiContext.lookup("java:/jcr/local");
>         Session s = rep.login(new SimpleCredentials(username, 
> username.toCharArray()));
>         Node node = s.getRootNode().addNode("aNode");
>         node.setProperty("aProperty", username);
>         s.save();
>         return node.getIdentifier();
>     }
>
> Note, that this method will automatically be encapsulated by a 
> container managed transaction. And due to the 
> bindSessionToTransaction-flag in the jcr-ds.xml, the
> JCASessionHandle used within the container managed transaction will be 
> automatically closed once the transaction commits (the 
> JCASessionHandle will be closed, the
> associated JCR session stays alive within the JCA connection pool).
> The above mentioned 3 steps of the simple test-case can now be 
> expressed as a sequence of method-calls of the stateless EJB:
>
> (1)jcrTest = (JCRTestBeanLocal) 
> jndiContext.lookup("test/JCRTestBean/local");
>     id = jcrTest.createNode(USER1);
>
> (2)jcrTest.alterProperty(id, USER2, USER2);
>
> (3)AssertJUnit.assertEquals(USER2, jcrTest.getProperty(id, USER1))
>
> However, this test-case fails, as in step (3) user 1 does not read the 
> changes committed by user 2. Interestingly the test-case passes once i 
> deactivate transaction
> support for step (1):
>
>     @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
>     public String createNode(String username) throws Exception {...}
>
> Does anyone know what i could do to make the test-case pass without 
> deactivating transaction support?
> Any hints would be really, really appreciated.
>
> Best regards,
> Dominik
>
>
> Below are the EJB-methods for the steps (2) and (3):
>
>     public void alterProperty(String id, String newValue, String 
> username) throws Exception {
>         InitialContext jndiContext = new InitialContext();
>         Repository rep = (Repository) 
> jndiContext.lookup("java:/jcr/local");
>         Session s = rep.login(new SimpleCredentials(username, 
> username.toCharArray()));
>         s.getNodeByIdentifier(id).setProperty("aProperty", newValue);
>         s.save();
>     }
>
>     public String getProperty(String id, String username) throws 
> Exception {
>         InitialContext jndiContext = new InitialContext();
>         Repository rep = (Repository) 
> jndiContext.lookup("java:/jcr/local");
>         Session s = rep.login(new SimpleCredentials(username, 
> username.toCharArray()));
>         return 
> s.getNodeByIdentifier(id).getProperty("aProperty").getString();
>     }

Mime
View raw message