Announcement Announcement Module
Collapse
No announcement yet.
Jta/JOTM in Tomcat, transaction rollback problem with two datasources Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Jta/JOTM in Tomcat, transaction rollback problem with two datasources

    Hi,
    this is an interesting problem i got, and an interesting architecture also ... But not sure yet if i'll be able to get all the components working together since i'm not using a J2EE application server like jBoss but Tomcat.

    So here's the architecture ....
    I'm working in a jsf portlet, this is a workflow portlet which use jBPM. I got two datasources, one where there is the jBPM schema, accessed through Hibernate; and another datasource that i access through Spring Jdbc Template.

    So the point is: inside a JBPM node action, i want to insert data in the second database ... both connection participating in same transaction.

    As i'm working on tomcat i've been using the out of box transaction manager JOTM. I've first made it work only with one datasource and jbpm, using hibernate jta transaction facilities (
    hibernate.transaction.factory_class=org.hibernate. transaction.JTATransactionFactory
    hibernate.transaction.manager_lookup_class=org.hib ernate.transaction.JOTMTransactionManagerLookup
    ).
    This has worked well, commit and rollback ok.

    Then i added the second datasource, accessed with the help of jdbctemplate and i used spring aop to transaction my service layer. Transaction is performed with spring facilities.
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager" />

    The logs i get are quite encouraging but the problem is what's in the log doesn't reflect what's happening in reality. The problem i got is that operations performed on the seconde datasource with jbpm template are commited instantaneously when i call "getJdbcTemplate().update(...)" although it's participating in another transaction that hasn't finished yet ....

    I don't know, maybe it's the expected behaviour, but the behaviour i want is the one i see in the log that i give you below. I want ( i'm throwing an exception just after the end of my jdbc transactional call ) the jta transaction to rollback both operation on both databases. So far, only jbpm rollback, the jdbc called has been performed and is not rollback when jbpm context close. I don't know if i make myself clear enough but it's tough to explain.


    Here are the explicit logs :
    you can see first transaction start (jbpm) and then spring transaction that participate in the first one, and then perform synchronization after end of second transaction . Then i throw the exception, so you can see the rollback .. but too late, data of the second transaction has been inserted already ... ;(

    -------------
    Logs in the next post
    -------------


    I don't know where to look for now ... If it's a spring configuration problem, jotm problem, xa datasource problem , i'm using oracle by the way ... i give you a bit of a conf if it can help ....


    spring :

    //datasource used with jbpm template
    <bean id="dataSource.nomina" class="org.springframework.jndi.JndiObjectFactoryB ean" scope="singleton">
    <property name="jndiName">
    <value>${jdbc.jndiName}</value>
    </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager" />


    hibernate :

    hibernate.connection.datasource=java:/comp/env/jdbc/jbpm
    hibernate.dialect=org.hibernate.dialect.Oracle9Dia lect
    hibernate.connection.driver_class=oracle.jdbc.driv er.OracleDriver
    cache.use_second_level_cache=false
    hibernate.cache.provider_class=org.hibernate.cache .HashtableCacheProvider
    hibernate.transaction.factory_class=org.hibernate. transaction.JTATransactionFactory
    hibernate.transaction.manager_lookup_class=org.hib ernate.transaction.JOTMTransactionManagerLookup

    tomcat context :

    jbpm datasource used in hibernate

    <Resource auth="Container"
    description="jbpm"
    name="jdbc/jbpm"
    type="javax.sql.DataSource"
    driverClassName="oracle.jdbc.xa.client.OracleXADat aSource"
    maxIdle="12"
    minIdle="8"
    maxWait="10000"
    removeAbandoned="true"
    logAbandoned="true"
    validationQuery="select 1 from dual"
    username="xxx"
    password="xxx"
    url="jdbc:oracle:thin:@xxx:1521:xxx"
    removeAbandonedTimeout="60"
    maxActive="120" />

    jotm transaction

    <Transaction factory="org.objectweb.jotm.UserTransactionFactory "
    jotm.timeout="60"/>

    second datasource used with jdbc template

    <Resource
    name="jdbc/seconddatabase"
    auth="Container"
    description="tresbases"
    type="javax.sql.DataSource"
    driverClassName="oracle.jdbc.xa.client.OracleXADat aSource"
    url="jdbc:oracle:thin:@xxx:1521:xxx"
    username="xxx"
    password="xxx"
    maxActive="20"
    />



    Any Idea ???

  • #2
    The logs

    Code:
      DEBUG org.jbpm.configuration.JbpmContextInfo : creating jbpm context with service factories '[tx, message, schedu
    ler, logging, persistence, authentication]'
      DEBUG org.jbpm.JbpmContext : creating org.jbpm.JbpmContext@3e31b4
      DEBUG org.jbpm.persistence.db.DbPersistenceServiceFactory : creating persistence service
      DEBUG org.jbpm.persistence.db.DbPersistenceService : creating hibernate session
      DEBUG org.jbpm.persistence.db.DbPersistenceService : beginning hibernate transaction
      DEBUG org.hibernate.transaction.JTATransaction : Looking for UserTransaction under: java:comp/UserTransaction
      DEBUG org.hibernate.transaction.JTATransaction : Obtained UserTransaction
      DEBUG org.hibernate.transaction.JTATransaction : begin
      DEBUG org.objectweb.jotm.Current : Current.getStatus()
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.Current : begin transaction
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.TransactionImpl : xid= bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.TransactionImpl : timeout= 60
      DEBUG org.objectweb.jotm.InternalTransactionContext : xid=bb14:38:0:011666c15b04ab7c9c...4ba808:, timeout=60
      DEBUG org.objectweb.jotm.TransactionImpl : myXid=bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.Current : tx=bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.doAttach flag= TMJOIN
      DEBUG org.objectweb.jotm.TransactionImpl : number of enlisted= 0
      DEBUG org.objectweb.jotm.Current : threadTx.set= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.Current : Associate tx to xid (xid=bb14:38:0:011666c15b04ab7c9c...4ba808:)
      DEBUG org.objectweb.jotm.TransactionImpl : myXid=bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.TransactionImpl : set timer for tx (timer=org.objectweb.jotm.TimerEvent@448e4f, tx=bb14:
    38:0:011666c15b04ab7c9c...4ba808:)
      DEBUG org.objectweb.jotm.TransactionImpl : myXid=bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.TransactionImpl : set date for tx (data=Wed Mar 19 37 VET 2008, tx=bb14:38:0:01166
    6c15b04ab7c9c...4ba808:)
      DEBUG org.hibernate.transaction.JTATransaction : Began a new JTA transaction
      DEBUG org.objectweb.jotm.Current : Current.getStatus()
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.getStatus()
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.getStatus()
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.registerSynchronization(Synchronization sync)
      DEBUG org.objectweb.jotm.TransactionImpl : make subcoordinator
      DEBUG org.objectweb.jotm.TransactionImpl : myXid=bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.SubCoordinator : tx=bb14:38:0:011666c15b04ab7c9c...4ba808:,  xid=bb14:38:0:011666c15b04a
    b7c9c...4ba808:
      DEBUG org.objectweb.jotm.SubCoordinator : synchro=org.hibernate.transaction.CacheSynchronization
      DEBUG org.objectweb.jotm.SubCoordinator : status=STATUS_ACTIVE
      DEBUG org.jbpm.persistence.db.DbPersistenceService : begun hibernate transaction org.hibernate.transaction.JTATra
    nsaction@405024
    37,930  DEBUG org.objectweb.jotm.Current : Current.getStatus()
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.getStatus()
      DEBUG org.objectweb.jotm.SubCoordinator : status=STATUS_ACTIVE
      DEBUG org.objectweb.jotm.Current : Current.getStatus()
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.getStatus()
      DEBUG org.objectweb.jotm.SubCoordinator : status=STATUS_ACTIVE
      DEBUG org.jbpm.context.exe.VariableContainer : update variable 'horasExtrasForm' in 'TokenVariableMap2c8490' to v
    alue 'com.odo.jbpm.horasextras.bean.HorasExtrasForm@1eda1f6'
      DEBUG org.jbpm.webapp.bean.TaskBean : Submitted button:Approbar
      DEBUG org.jbpm.graph.def.GraphElement : executing action 'Action(2d928c)'
      DEBUG org.jbpm.graph.exe.Token : token[1804] is locked by token[1804]
      DEBUG org.springframework.transaction.support.AbstractPlatformTransactionManager : Using transaction object [org.
    springframework.transaction.jta.JtaTransactionObject@2eaba8]
      DEBUG org.objectweb.jotm.Current : Current.getStatus()
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.getStatus()
      DEBUG org.objectweb.jotm.SubCoordinator : status=STATUS_ACTIVE
      DEBUG org.springframework.transaction.support.AbstractPlatformTransactionManager : Participating in existing tran
    saction
      DEBUG org.springframework.transaction.interceptor.TransactionAspectSupport : Getting transaction for [com.odo.
    core.service.EmployeeInfoService.setEmployee]
      DEBUG com.odo.core.dao.EmployeeInfoSPDaoImpl : createEmployee(String email=1803) - start
      DEBUG org.springframework.transaction.interceptor.TransactionAspectSupport : Completing transaction for [com.oran
    ge.core.service.EmployeeInfoService.setEmployee]
      DEBUG org.springframework.transaction.support.AbstractPlatformTransactionManager : Triggering beforeCommit synchr
    onization
      DEBUG org.springframework.transaction.support.AbstractPlatformTransactionManager : Triggering beforeCompletion sy
    nchronization
      DEBUG org.springframework.transaction.support.AbstractPlatformTransactionManager : Triggering afterCommit synchro
    nization
      DEBUG org.springframework.transaction.jta.JtaTransactionManager : Registering after-completion synchronization wi
    th existing JTA transaction
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.registerSynchronization(Synchronization sync)
      DEBUG org.objectweb.jotm.SubCoordinator : synchro=org.springframework.transaction.jta.JtaAfterCompletionSynchroni
    zation@31b870
      DEBUG org.objectweb.jotm.SubCoordinator : status=STATUS_ACTIVE
      DEBUG org.jbpm.graph.exe.Token : token[1804] is unlocked by token[1804]
      ERROR org.jbpm.graph.def.GraphElement : action threw exception: null
    java.lang.Exception
            at com.odo.jbpm.actionhandler.SendEmailActionHandler.execute(SendEmailActionHandler.java:33)
    		------------------------------------------
      ERROR org.jbpm.webapp.portlet.MyFacesJbpmGenericPortlet : Exception during process action, closing jbpm context
      DEBUG org.jbpm.JbpmContext : closing jbpmContext org.jbpm.JbpmContext@3e31b4
      DEBUG org.jbpm.svc.Services : closing service 'persistence': org.jbpm.persistence.db.DbPersistenceService@f618a6
      DEBUG org.jbpm.persistence.db.DbPersistenceService : rolling back hibernate transaction
      DEBUG org.hibernate.transaction.JTATransaction : rollback
      DEBUG org.objectweb.jotm.Current : Current.rollback()
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.objectweb.jotm.Current : threadTx.set= null
      DEBUG org.objectweb.jotm.TransactionImpl : myXid=bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.rollback(tx= bb14:38:0:011666c15b04ab7c9c...4ba808:)
      DEBUG org.objectweb.jotm.SubCoordinator : status=STATUS_ACTIVE
      DEBUG org.objectweb.jotm.TransactionImpl : TransactionImpl.doDetach flag= TMSUCCESS
      DEBUG org.objectweb.jotm.TransactionImpl : number of enlisted= 0
      DEBUG org.objectweb.jotm.SubCoordinator : transaction rolling back
      DEBUG org.objectweb.jotm.SubCoordinator : doBeforeCompletion committing= false
      DEBUG org.objectweb.jotm.TransactionImpl : myXid=bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.TransactionImpl : unset timer for tx (timer=org.objectweb.jotm.TimerEvent@448e4f, tx=bb1
    4:38:0:011666c15b04ab7c9c...4ba808:)
      DEBUG org.objectweb.jotm.SubCoordinator : SubCoordinator.doRollback()
      DEBUG org.objectweb.jotm.SubCoordinator : doAfterCompletion()
      DEBUG org.objectweb.jotm.SubCoordinator : sychronization list size= 2
      DEBUG org.objectweb.jotm.SubCoordinator : Synchronization sync= org.hibernate.transaction.CacheSynchronization
      DEBUG org.objectweb.jotm.SubCoordinator : sync.afterCompletion status= STATUS_ROLLEDBACK
      DEBUG org.objectweb.jotm.SubCoordinator : Synchronization sync= org.springframework.transaction.jta.JtaAfterCompl
    etionSynchronization@31b870
      DEBUG org.objectweb.jotm.SubCoordinator : sync.afterCompletion status= STATUS_ROLLEDBACK
      DEBUG org.objectweb.jotm.TransactionImpl : myXid=bb14:38:0:011666c15b04ab7c9c...4ba808:
      DEBUG org.objectweb.jotm.Current : remove tx from xid (xid=bb14:38:0:011666c15b04ab7c9c...4ba808:)
      DEBUG org.objectweb.jotm.SubCoordinator : SubCoordinator unexported [subcoord=org.objectweb.jotm.SubCoordinator@4
    61904]
      DEBUG org.hibernate.transaction.JTATransaction : Rolled back JTA UserTransaction
      DEBUG org.objectweb.jotm.Current : Current.getStatus()
      DEBUG org.objectweb.jotm.Current : threadTx.get= java.lang.ThreadLocal@15c505e
      DEBUG org.jbpm.persistence.db.DbPersistenceService : closing hibernate session
      DEBUG org.jbpm.svc.Services : closing service 'tx': org.jbpm.tx.TxService@428a96
      DEBUG org.jbpm.svc.Services : closing service 'authentication': org.jbpm.security.authentication.DefaultAuthentic
    ationService@f618b0

    Comment


    • #3
      By the way, nobody was replying and i needed it to work so what i did is carried out a simple app which uses two spring jdbc with two datasources with jta transaction...
      Here is what i do :
      start service ( service is transactional )
      insert data in database 1
      start transaction ( supposed to be the same and it is what i see in the log, participating in existing transaction )
      insert data in database 2
      throw null pointer exception ....

      This works pretty well on jboss, i used jboss transaction manager with spring jta and i configured the datasource as xa datasources in jboss .... When no exception thrown, both commit, when null pointer, both rollback ! great !!!!


      So i carried this application inside tomcat, because the main goal is to make it work on tomcat, that's why i need ....
      so same code, but datasources declared in context.xml ( configuration i gave in the previous post ), and jotm transaction manager ....
      Same logs ( kind of because its jotm and not jboss ) ...
      but rollback is only effective in the logs ... inside the database, both data are insert in both database .....


      So can someone help me ????
      There's only three possibilities now for the problem ...
      - Does it come from datasource configuration ??
      - Does it come from transaction manager ?? JTOM is supposed to suport two faces commit, isn't it ?
      - Does it come from the server ? said other way, is tomcat able to manage distributed transaction with help of jta/jotm ....


      PLEASE HELP !!!! i can't be more explicit

      Comment


      • #4
        Hi,

        The problem is most certainly due to JOTM and its XAPool. How about trying another transaction manager ? For instance, you can try Atomikos which is also open source: http://www.atomikos.com/products.html

        You can easily replace JOTM with Atomikos just by changing your configuration. Have a look at this page to know more about what the integration possibilities with Tomcat are: http://wiki.atomikos.org/Documentati...catIntegration

        I hope this helps.
        Ludovic

        Comment


        • #5
          Yes it was that
          the problem was not from the side of the developer
          I turned to Atomikos and yeah ( both insert statements in both database rollbacks ) !!!

          GREAAAAAAAAAATTTTTTTTTTTT ! I love jta !

          Comment


          • #6
            hi,

            I'm facing the same problem (jBPM process updating other database from ActionHandler) but all I get is exceptions although I use Atomikos. I'd appreciate if you gave me more information about your datasource config both for tomcat and hibernate

            my context.xml (for tomcat)

            <Resource auth="Container" name="jdbc/xa/jbpm" description="jbpm" factory="org.apache.naming.factory.BeanFactory" type="oracle.jdbc.xa.client.OracleXADataSource" user="greg"
            password="greg" URL="jdbc:oracle:thin:@hudson:1521:db1"
            />

            <Resource auth="Container" name="DataSourceXA" type="com.atomikos.jdbc.DataSourceBean" validatingQuery="" dataSourceName="jdbc/xa/jbpm" exclusiveConnectionMode="false"
            uniqueResourceName="jdbc/atomikos/jbpm" connectionTimeout="20"
            xidFormat="Default" factory="org.apache.naming.factory.BeanFactory"
            connectionPoolSize="20"
            />

            hibernate
            <property name="hibernate.transaction.manager_lookup_class"> com.atomikos.icatch.jta.hibernate3.TransactionMana gerLookup</property>
            <property name="hibernate.transaction.factory_class">org.hib ernate.transaction.JTATransactionFactory</property>
            <property name="jta.UserTransaction">java:comp/envUserTransaction</property>
            <property name="hibernate.current_session_context_class">jta </property>
            <property name="hibernate.connection.release_mode">on_close</property>
            <property name="hibernate.connection.datasource">java:comp/env/DataSourceXA</property>

            spring
            <bean id="xaTransactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager" lazy-init="true">
            <property name="userTransaction" ref="userTransaction" />
            <property name="transactionManager" ref="userTransactionManager"/>
            </bean>
            <bean id="dataSourceXA" class="org.springframework.jndi.JndiObjectFactoryB ean">
            <property name="jndiName">
            <value>java:comp/env/DataSourceXA</value>
            </property>
            </bean>

            jbpm.cfg.xml
            ..
            <bean class="org.jbpm.persistence.jta.JtaDbPersistenceSe rviceFactory">
            <field name="isTransactionEnabled"><false /></field>
            <field name="isCurrentSessionEnabled"><true /></field>
            <field name="dataSourceJndiName"><string value="java:comp/env/DataSourceXA" /></field>
            </bean>
            ..

            The problem is that if I start my transaction from some other place rather that from ActionHandler
            class...
            void func(){
            transactionManager.getTransaction(defaultTransacti on)
            ..

            }

            everything works fine (rollbacks)

            but when the first method which goes to other database comes from ActionHandler than it doesnt work (the scenario for this is that I've two ActionHandlers A1 & A2 if A2 throws exception jBPM rollbacks but A1 doesn't rollback!!!

            i'd appreciate any help as I've been trying to fix it for the couple of days

            regards

            Comment

            Working...
            X