I guess the best way to go will be to set up Jackrabbit as JCA resource adapter -- then you will not have to deal with the internals of XA related stuff. Google for Jacrabbit JCA, you should get some good hints.
Regards, Vijay -----Original Message----- From: Gadbury [mailto:[email protected]] Sent: Monday, August 03, 2009 9:54 AM To: [email protected] Subject: Re: User Managed Transactions... Hi Ian, Thanks for the advice. In the meantime, I have got container-managed transactions working using the XAResource. I'm not even sure if what I am doing is right any more! It seems a bit belt-and-braces for what I want to do (ensure I can reliably use newly assigned UUIDs without persisting transient session changes until my whole unit of work is complete). Here is an example I wrote - if anyone happens to see a glaring mistake or problem, please let me know. /* * Dominique: "Before a transactional resource is handed out to a client, an * application server will associate its global transaction with the * resource (i.e. invoke XAResource.start). The client will invoke * methods on the non-XA part of the resource and at the end of the * request, the application server will disassociate the resource * (i.e. invoke XAResource.end) before eventually committing or * rolling back changes on all resources involved in the global * transaction". */ Xid xid = new Xid() { public byte[] getBranchQualifier() { return new byte[0]; } public int getFormatId() { return 0; } public byte[] getGlobalTransactionId() { return new byte[0]; } }; try { //My custom getSession() method returns a Session - cast to XASession. xaSession = (XASession) getSession(); xaResource = xaSession.getXAResource(); xaResource.start(xid, XAResource.TMNOFLAGS); boolean commitSuccessful = false; /* * Now we've marked the start of our transaction with * xaResource.start(), we can add our nodes and properties */ Node rootNode = xaSession.getRootNode(); Node someNode = rootNode.addNode("some_node"); someNode.setProperty("name", "some name"); xaSession.save(); // This will not persist the changes as we're in transaction scope. Node anotherNode = someNode.addNode("another_node"); anotherNode.setProperty("date", Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.UK)); xaSession.save(); // Last save before commit // Finally commit this transaction to persist the changes made to xaSession. xaResource.end(xid, XAResource.TMSUCCESS); xaResource.prepare(xid); xaResource.commit(xid, false); commitSuccessful = true; } catch (Exception e) { // Handle exceptions better than this! } finally { if (commitSuccessful == false) { logger.error("Commit unsuccessful"); if (xaResource != null) { try { xaResource.end(xid, XAResource.TMFAIL); } catch (XAException e) { logger.error("Error ending transaction: " + e.getMessage()); } } } xaSession.logout(); // Finally release the session (whether commit was successful or not). } Ian Boston wrote: > > Unfortunately I dont have any experience of JOTM, so I dont know if it > will work with Jackrabbit. I do know that Geronimo's JTA works. There > was another one mentioned on the lists a while back. JOTM says is does > support XA so *should* work with Jackrabbit... if you an hold of a > functional transaction manager. > > There is a JMS example on the JOTM site that uses XA, (might help ?) > Ian > > On 3 Aug 2009, at 11:50, Gadbury wrote: > >> >> Thank you Ian for your response. I appreciate it. Unfortunately, I >> am now a >> bit lost, going around in circles and banging my head against a >> brick wall >> :) >> >> I am using Tomcat 6.0 + JOTM 2.1.4 (also, I am not using spring- >> modules-jcr) >> and I am able to get my UserTransaction via JNDI (it is casted from an >> org.objectweb.jotm.Current object, which implements javax.transaction >> TransactionManager and UserTransaction interfaces). I have also tried >> casting the Current object to TransactionManager and calling >> transactionManager.getTransaction(), but no Transaction is returned. >> >> I'm not sure what else to try. I thought Jackrabbit did support >> user and >> container-managed transactions...? There seems to be no easy way >> for me to >> retrieve a Transaction or TransactionManager object with the setup I >> am >> using (although most likely I am just being stupid!). I have had a >> look at >> the container-managed transactions part of the JCR 1.0 spec >> (associating the >> resource with a global transaction using the myXAResource.start(xid, >> TMNOFLAGS) and myXAResource.end(xid, TMSUSPEND); ), but that seems a >> bit >> heavy-weight. By the way, what happened to the XIDHelper class? >> >> Is there anyone out there that uses Tomcat, JOTM and transactions? >> >> >> Ian Boston wrote: >>> >>> I will have a go at answering, but no guarantees :) >>> On 1 Aug 2009, at 11:56, Gadbury wrote: >>> >>>> >>>> Hi Ian, >>>> >>>> Thank you for the pointers. Was I wrong to use UserTransaction? >>> >>> I think (but I could be completely wrong), UserTransaction is >>> generally a wrapper for the TransactionManager so when you create a >>> user transaction jndi will associate the user transaction with the >>> TransactionManager, and then the UserTransaction will proxy the >>> remaining calls through to the TransactionManager (at least thats the >>> case with Geronimo) >>> >>> You need to bind the JCR session into the transaction, which cant be >>> done with a UserTransaction where the wiring is within the >>> TransactionManager impl, usually bound to the JDBC data source. So >>> your right to use UserTransaction for JDBC/Datasource, but wrong to >>> use it for JCR. (IIRC) >>> >>>> What type >>>> of tranasction is that in your example It looks to me like you're >>>> using >>>> Transaction and TransactionManager interfaces from >>>> javax.transaction. >>> >>> yes >>> >>>> How >>>> do I get a TransactionManager instance? Can I still use JNDI or is >>>> there an >>>> alternative (in fact, JNDI presents me a problem with unit testing >>>> as >>>> without the web application running on the Tomcat server, the JNDI >>>> lookup >>>> cannot get the UserTransaction instance) ? >>> >>> you *should* be able to look up the transaction manager from jNDI >>> *or* >>> for unit testing, create a new instance of the TransactionManager. I >>> have been using Geronimo in OSGi with Sling/Jackrabbit and its just a >>> new GeronimoTransactionManager(defaultTransactionTimeoutSeconds); to >>> get one (only one per transaction context) >>> >>>> >>>> Sorry for the silly questions. Thanks for your time. Regards, >>>> >>>> James >>>> >>>> >>>> Ian Boston wrote: >>>>> >>>>> IIRC you have to bind the jcr session to the transaction. In >>>>> Jackrabbit the session is actually an XASession with a >>>>> getXAResource() >>>>> method so you can bind the session with something like this. >>>>> >>>>> Transaction transaction = transactionManager.getTransaction(); >>>>> if (transaction != null) { >>>>> >>>>> transaction.enlistResource(((XASession)session).getXAResource()); >>>>> } >>>>> >>>>> >>>>> HTH >>>>> Ian >>>>> >>>>> On 31 Jul 2009, at 17:26, Gadbury wrote: >>>>> >>>>>> >>>>>> Hi all, >>>>>> >>>>>> I have finally managed to get somewhere with jotm and Tomcat 6.0 >>>>>> having >>>>>> followed the tutorial provided in the above links. I am finally >>>>>> getting the >>>>>> UserTransaction via JNDI lookup (after classloader issues and >>>>>> naming >>>>>> exceptions) and I am testing that new >>>>>> InitialContext().lookup("java:comp/UserTransaction"); is an >>>>>> instance >>>>>> of >>>>>> UserTranasction. >>>>>> >>>>>> Unfortunately, every session.save() called in between the >>>>>> utx.begin() and >>>>>> utx.commit() persists changes so the UserTranasction is not having >>>>>> an >>>>>> effect. I was hoping that session.save() would not persist >>>>>> changes >>>>>> in the >>>>>> scope of a UserTranasction but would ensure that node UUIDs are >>>>>> permanently >>>>>> assigned to new nodes. For example: >>>>>> >>>>>> Session session = getSession(); >>>>>> >>>>>> // Get user transaction (for example, through JNDI) >>>>>> UserTransaction utx = (UserTransaction) new >>>>>> InitialContext().lookup("java:comp/UserTransaction"); >>>>>> >>>>>> JcrUserDao userDao = new JcrUserDao(); >>>>>> JcrProductDao productDao = new JcrProductDao(); >>>>>> >>>>>> utx.begin(); >>>>>> >>>>>> Node newUserNode = userDao.create(aUser, session); >>>>>> >>>>>> session.save(); >>>>>> >>>>>> String UUID = newUserNode.getUUID(); >>>>>> >>>>>> Node newProductNode = productDao.create(aProduct, session); >>>>>> >>>>>> session.save(); >>>>>> >>>>>> utx.commit(); >>>>>> >>>>>> If I step through the above code in debug within Eclipse, and >>>>>> terminate the >>>>>> Tomcat server after the first session.save() but before the >>>>>> utx.commit(), I >>>>>> can see that the the changes are made by the first Dao method call >>>>>> userDao.create(aUser, session) are persisted. >>>>>> >>>>>> So far I have put all the required jotm jars in %TOMCAT_HOME%/lib >>>>>> from the >>>>>> distribution bundle jotm 2.1.4. >>>>>> >>>>>> My context.xml is configured with: >>>>>> >>>>>> <Transaction factory="org.objectweb.jotm.UserTransactionFactory"/> >>>>>> >>>>>> >>>>>> My carol.properties is saved in WEB-INF/Classes and is as follows: >>>>>> >>>>>> # JNDI (Protocol Invocation) >>>>>> carol.protocols=jrmp >>>>>> >>>>>> # Local RMI Invocation >>>>>> carol.jvm.rmi.local.call=true >>>>>> >>>>>> # do not use CAROL JNDI wrapper >>>>>> carol.start.jndi=false >>>>>> >>>>>> # do not start a name server >>>>>> carol.start.ns=false >>>>>> >>>>>> # Naming Factory >>>>>> carol.jndi.java.naming.factory.url.pkgs=org.apache.naming >>>>>> >>>>>> >>>>>> Is there some further configuration required? No exceptions are >>>>>> being >>>>>> thrown any more and the UserTransaction is retrieved via JNDI >>>>>> lookup >>>>>> yet the >>>>>> UserTranasction appears not to be functioning as expected. >>>>>> >>>>>> Any advice would be greatly appreciated. Thanks for your time. >>>>>> Regards, >>>>>> >>>>>> James. >>>>>> >>>>>> >>>>>> >>>>>> Vijay Pandey wrote: >>>>>>> >>>>>>> There might be a line break and you might not be copying the full >>>>>>> URL. I >>>>>>> just checked and the URL is alive. >>>>>>> >>>>>>> -----Original Message----- >>>>>>> From: Gadbury [mailto:[email protected]] >>>>>>> Sent: Thursday, July 30, 2009 3:59 PM >>>>>>> To: [email protected] >>>>>>> Subject: RE: User Managed Transactions... >>>>>>> >>>>>>> >>>>>>> Thank you Vijay, I shall take a closer look tomorrow. By the >>>>>>> way, >>>>>>> the >>>>>>> second >>>>>>> link gives me a 404. >>>>>>> >>>>>>> Cheers, >>>>>>> >>>>>>> James >>>>>>> >>>>>>> >>>>>>> Vijay Pandey wrote: >>>>>>>> >>>>>>>> You might want to take a look at this >>>>>>>> >>>>>>>> >>>>>>> http://static.raibledesigns.com/downloads/howto-tomcat-jotm.html#5.5-config >>>>>>>> >>>>>>>> along with this >>>>>>>> >>>>>>>> >>>>>>> http://www.nabble.com/Re%3A-UserTransaction%2C-JOTM-and-Tomcat-5.5.x-p288894 >>>>>>>> 3.html >>>>>>>> >>>>>>>> Vijay >>>>>>>> >>>>>>>> -----Original Message----- >>>>>>>> From: Gadbury [mailto:[email protected]] >>>>>>>> Sent: Thursday, July 30, 2009 2:17 PM >>>>>>>> To: [email protected] >>>>>>>> Subject: Re: User Managed Transactions... >>>>>>>> >>>>>>>> >>>>>>>> Hi again all. >>>>>>>> >>>>>>>> I have been trying to get javax.transaction.UserTransaction >>>>>>>> working by >>>>>>>> JNDI >>>>>>>> lookup. I use Eclipse Galileo and Tomcat 6.0. I am trying >>>>>>>> trying >>>>>>>> retreive >>>>>>>> a UserTransaction as follows (I have tried both): >>>>>>>> >>>>>>>> UserTransaction utx = new >>>>>>>> InitialContext().lookup("java:comp/UserTransaction"); >>>>>>>> >>>>>>>> UserTransaction utx = new >>>>>>>> InitialContext().lookup("java:comp/env/UserTransaction"); >>>>>>>> >>>>>>>> However, an exception is thrown stating that I must setup a >>>>>>>> system >>>>>>>> or >>>>>>>> environment property, or the application context. Do I need to >>>>>>>> configure >>>>>>>> the resource and / or environment elements in context.xml? For >>>>>>>> example, >>>>>>>> the >>>>>>>> resource configuration: >>>>>>>> >>>>>>>> <context> >>>>>>>> <Resource name="UserTransaction" auth="Container" >>>>>>>> type="javax.transaction.UserTransaction"/> >>>>>>>> <ResourceParams name="UserTransaction"> >>>>>>>> <parameter> >>>>>>>> <name>factory</name> >>>>>>>> <value>org.objectweb.jotm.UserTransactionFactory</value> >>>>>>>> </parameter> >>>>>>>> <parameter> >>>>>>>> <name>jotm.timeout</name> >>>>>>>> <value>60</value> >>>>>>>> </parameter> >>>>>>>> </ResourceParams> >>>>>>>> </context> >>>>>>>> >>>>>>>> Does Tomcat 6.0 support UserTransaction by JNDI, or do I need to >>>>>>>> use >>>>>>>> another >>>>>>>> technology such as JOTM or Jencks? Ideally I wouldn't have to >>>>>>>> install >>>>>>>> and >>>>>>>> configure one of the other technologies. >>>>>>>> >>>>>>>> Thanks for reading. Kind regards, >>>>>>>> >>>>>>>> James >>>>>>>> -- >>>>>>>> View this message in context: >>>>>>>> >>>>>>> http://www.nabble.com/User-Managed-Transactions...-tp24687924p24745618.html >>>>>>>> Sent from the Jackrabbit - Users mailing list archive at >>>>>>>> Nabble.com. >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> View this message in context: >>>>>>> http://www.nabble.com/User-Managed-Transactions...-tp24687924p24747221.html >>>>>>> Sent from the Jackrabbit - Users mailing list archive at >>>>>>> Nabble.com. >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> View this message in context: >>>>>> http://www.nabble.com/User-Managed-Transactions...-tp24687924p24759260.html >>>>>> Sent from the Jackrabbit - Users mailing list archive at >>>>>> Nabble.com. >>>>>> >>>>> >>>>> >>>>> >>>> >>>> -- >>>> View this message in context: >>>> http://www.nabble.com/User-Managed-Transactions...-tp24687924p24768096.html >>>> Sent from the Jackrabbit - Users mailing list archive at Nabble.com. >>>> >>> >>> >>> >> >> -- >> View this message in context: >> http://www.nabble.com/User-Managed-Transactions...-tp24687924p24788686.html >> Sent from the Jackrabbit - Users mailing list archive at Nabble.com. >> > > > -- View this message in context: http://www.nabble.com/User-Managed-Transactions...-tp24687924p24792235.html Sent from the Jackrabbit - Users mailing list archive at Nabble.com.
