3 Replies Latest reply on Feb 18, 2014 12:26 PM by emedina2014

    Controlling Transaction Management

    drakemj

      Background

      I configured Jackrabbit (2.4.3) for a JBoss server (jboss-as-7.1.1.Final), by following the instructions here:

      http://web.archive.org/web/20110921034713/http://community.jboss.org/wiki/JackrabbitDeploymentInAS6AndAS7

      The relevant portions of my configuration are included at the end of this post.

       

      Our application calls Jackrabbit under transaction management, within an EJB.  From what I understand, the database connection configured for use with Jackrabbit cannot be under the control of an external transaction manager.  I’ve read that “Jackrabbit implements distributed XA transaction support on a higher level, and expects to be in full control of the underlying database connection.” and “You can still do transactions with Jackrabbit, but you'll have to configure the transaction manager to work on top of Jackrabbit (using XASessions as the managed resources) instead of below Jackrabbit on the persistence layer.”

       

      Question

      My question is, how does one configure the transaction manager to satisfy these requirements?  Unfortunately, I’m not sure whether this is an EJB setting, a datasource setting, part of the Jackrabbit configuration, or something else altogether.

       

      A Related Error

      Once Jackrabbit was configured, I noticed this (ironjacamar 1.0.9) error in my server log:

       

      Caused by: java.sql.SQLException: You cannot set autocommit during a managed transaction!
                      at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:888)
                      at org.jboss.jca.adapters.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:715)
                      at org.apache.jackrabbit.core.util.db.ConnectionHelper.getConnection(ConnectionHelper.java:439)
                      at org.apache.jackrabbit.core.util.db.ConnectionHelper.reallyExec(ConnectionHelper.java:390)
                      at org.apache.jackrabbit.core.util.db.ConnectionHelper$3.call(ConnectionHelper.java:378)
                      at org.apache.jackrabbit.core.util.db.ConnectionHelper$3.call(ConnectionHelper.java:374)
                      at org.apache.jackrabbit.core.util.db.ConnectionHelper$RetryManager.doTry(ConnectionHelper.java:567)
                      at org.apache.jackrabbit.core.util.db.ConnectionHelper.exec(ConnectionHelper.java:374)
                      at org.apache.jackrabbit.core.fs.db.DatabaseFileSystem.verifyRootExists(DatabaseFileSystem.java:879)
      

      This particular error codes from line 888 of http://grepcode.com/file/repository.jboss.org/nexus/content/repositories/releases/org.jboss.ironjacamar/ironjacamar-jdbc/1.0.9.Final/org/jboss/jca/adapters/jdbc/BaseWrapperManagedConnection.java?av=fhttp://

       

      I found that this error is the result of being in a managed transaction.  The errors can be ignored (bypassed) by setting the ironjacamar.jdbc.ignoreautocommit system property to true.  (I did this in standalone.xml.)  Admittedly, this is a questionable fix.  With this fixed, I get another string of errors.  Rather than going down this other path of errors, I thought it was best to address the transaction manager configuration first.

       

       

      My Configuration

       

      1. jackrabbit-jca.rar\META-INF\MANIFEST.MF

      Manifest-Version: 1.0
      Archiver-Version: Plexus Archiver
      Created-By: Apache Maven
      Built-By: bart
      Build-Jdk: 1.6.0_34
      Dependencies: javax.jcr export,org.slf4j
      

       

      2. Standalone.xml (relevant excerpts only)

       <system-properties>
              <!—other properties omitted -- >
              <property name="ironjacamar.jdbc.ignoreautocommit" value="true"/>
       </system-properties>
      
       <datasource jndi-name="java:/MyAppRepo" pool-name="MyAppRepo" enabled="true">
           <connection-url>jdbc:oracle:thin:@localhost:1521:XE</connection-url>
            <driver>oracle</driver>
            <security>
                 <user-name>MyAppRepo</user-name>
                 <password>MyAppRepo</password>
            </security>
       </datasource>
      
       <resource-adapter>
            <archive>
            jackrabbit-jca.rar
            </archive>
            <transaction-support>XATransaction</transaction-support>
            <connection-definitions>
                 <connection-definition class-name="org.apache.jackrabbit.jca.JCAManagedConnectionFactory" jndi-name="java:/jca/MyApp" enabled="true" use-java-context="true" pool-name="jackrabbit-jca-1_6_1_rar-Pool" use-ccm="true">
                      <config-property name="HomeDir">
                          ${jboss.server.config.dir}/../../../repository
                      </config-property>
                      <config-property name="ConfigFile">
                           ${jboss.server.config.dir}/repository.xml
                      </config-property>
                 </connection-definition>
            </connection-definitions>
       </resource-adapter>
      

       

      3. Repository.xml

      See attachment

       

      Thanks!

        • 1. Re: Controlling Transaction Management
          jaikiran

          I've zero knowledge about Jackrabbit. Based on what you have posted, it looks like you/Jackrabbit are fetching a connection from the datasource and trying to set aut commit on it. Now since it's part of a managed transaction, you aren't allowed to do that. Perhaps you need a connection which doesn't get enrolled in the transaction, so that you can manage it on your own? If so, set the jta = false attribute https://github.com/jbossas/jboss-as/blob/master/build/src/main/resources/docs/schema/jboss-as-datasources_1_1.xsd#L199 in the datasource configuration of your standalone.xml file.

          • 2. Re: Controlling Transaction Management
            kdolan1

            I'm Melanie's coworker...

             

            Setting jta=false eliminated the autocommit message but now we see a warning that is concerning:

             

            14:08:55,910 WARN  [com.arjuna.ats.jta] ARJUNA016039: onePhaseCommit on 
            < formatId=131077, gtrid_length=29, bqual_length=36, tx_uid=0:ffffc0a8b9a7:-7037166:50f99da3:31, 
            node_name=1, branch_uid=0:ffffc0a8b9a7:-7037166:50f99da3:33, subordinatenodename=null, 
            eis_name=java:/jca/horizon > (XAResourceWrapperImpl@190ef9d[xaResource=org.apache.jackrabbit.jca.TransactionBoundXAResource@1527d0 
            pad=false overrideRmValue=false productName=Jackrabbit productVersion=2.4.3 jndiName=java:/jca/horizon]) 
            failed with exception -: java.lang.IllegalStateException... with a following stack trace
            

             

            Ultimately what we are trying to achieve is getting Jackrabbit 2.4.3 (a JCR implementation) that is embedded in our application running in JBoss 7.1.1 and I'm getting the feeling we don't totally understand how transaction management is configured and/or works entirely. While we can try different configurations to find one that doesn't cause errors/warnings to appear in our logs, I want to make sure we understand the impact of our choices to ensure it achieves what we need.

             

            About our application:

            * It has a session EJB and in the EJB implementation, calls Jackrabbit APIs.

            * It has a set of database tables in more than one tablespace. As a result, our database connections are configured to be XA datasources.

            * Jackrabbit also has a set of database tables in yet another tablespace.

            * An operation typically involves a DB update to both our application database tables and the Jackrabbit tables. Therefore, if one or the other fails we need everything to roll back.

            * Per the Jackrabbit documentation:

            If you use a database persistence manager, the configured database connection must not be under the control of an external transaction manager. Jackrabbit implements distributed XA transaction support on a higher level, and expects to be in full control of the underlying database connection.

             

            I think we're missing how to configure JBoss that meets Jackrabbit's conditions - full control of the underlying db connection but part of a higher-level XA transaction.

             

            Thanks! All help is appreciated.

            • 3. Re: Controlling Transaction Management
              emedina2014

              Did you eventually manage to solve this issue? I'm also facing it and I can work around it with the jta="false", but a bit scary...

               

              Any help would be really appreciated.