Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Distributed Transaction in Standalone Application

  1. #1
    Join Date
    Sep 2005
    Location
    Hong Kong, China
    Posts
    33

    Default Distributed Transaction in Standalone Application

    Hi,

    I am developing a standalone Java application using Oracle. In order to have distributed transaction, I looked up a JTA transaction manager from WebLogic server and bind the data source to it. Shown below is the configuration:

    <bean id="dataSourceAbstract" class="javax.sql.DataSource" abstract="true">
    <property name="driverClassName">
    <value>${jdbc.driverClassName}</value>
    </property>
    <property name="url">
    <value>${jdbc.url}</value>
    </property>
    <property name="username">
    <value>${jdbc.username}</value>
    </property>
    <property name="password">
    <value>${jdbc.password}</value>
    </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    lazy-init="true" parent="dataSourceAbstract">

    </bean>

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

    <bean id="txProxyTemplate" abstract="true"
    class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
    <property name="transactionManager">
    <ref bean="transactionManager" />
    </property>
    <property name="transactionAttributes">
    <props>
    <prop key="*">PROPAGATION_REQUIRED</prop>
    </props>
    </property>
    </bean>

    <bean id="customerContractCache" parent="txProxyTemplate" singleton="true">
    <property name="target">
    <bean class="foo.Test">
    <property name="clientManager">
    <ref bean="clientManager" />
    </property>
    </property>
    </bean>

    <bean id="clientManager" parent="txProxyTemplate" singleton="true">
    <property name="target">
    <bean class="foo.clientManagerImpl">
    <property name="clientDAO">
    <ref bean="clientDAO" />
    </property>
    </property>
    </bean>

    <bean id="sqlMapClient"
    class="org.springframework.orm.ibatis.SqlMapClient FactoryBean">
    <property name="configLocation">
    <value>
    classpath:/foo/sql-map-config.xml
    </value>
    </property>
    </bean>

    <bean id="clientDAO"
    class="foo.ClientDAOImpl">
    <property name="dataSource">
    <ref bean="dataSource" />
    </property>
    <property name="sqlMapClient">
    <ref bean="sqlMapClient" />
    </property>
    </bean>


    However, I found that transaction is committed each time function in foo.Test is executed. Even thought a RuntimeException was thrown intentionally at the end of a function, transaction is not rollback.

    I would like to know what's wrong with the configuration?

    Thanks.

    Regards,
    Koala Lam

  2. #2
    Join Date
    Sep 2004
    Posts
    1,086

    Default

    You are trying to use a local datasource with jta transaction manager, and that can't work. You need to use XADatasource, XA capable driver and XA capable db server.

  3. #3
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Koala, this topic has been discussed quite a lot on the forum - search for JTA and distribution transactions and you'll find plenty of posts.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  4. #4
    Join Date
    Oct 2004
    Location
    Fareham, England
    Posts
    313

    Default

    Hi Koala

    This section of the Spring reference documentation, although quite small, does state the relationship between the DataSource and the concrete PlatformTransactionManager type.

    Cheers
    Rick

  5. #5
    Join Date
    Sep 2005
    Location
    Hong Kong, China
    Posts
    33

    Default

    Hi,

    I am actually using a XADataSource. Shown below is the JDBC configuration which is loaded using a PropertyPlaceholderConfigurer:

    jdbc.driverClassName=oracle.jdbc.xa.client.OracleX ADataSource
    jdbc.url=jdbc:oracle:thin:@192.168.88.229:1521:tes t3
    jdbc.username=test
    jdbc.password=test

    The log shows that transaction is rollback, however, changes are indeed committed:

    2006-10-18 11:21:21,222 [main] DEBUG org.springframework.transaction.interceptor.RuleBa sedTransactionAttribute.rollbackOn(119) - Applying rules to determine whether transaction should rollback on java.lang.RuntimeException
    2006-10-18 11:21:21,222 [main] DEBUG org.springframework.transaction.interceptor.RuleBa sedTransactionAttribute.rollbackOn(137) - Winning rollback rule is: null
    2006-10-18 11:21:21,222 [main] DEBUG org.springframework.transaction.interceptor.RuleBa sedTransactionAttribute.rollbackOn(143) - No relevant rollback rule found: applying superclass default
    2006-10-18 11:21:21,222 [main] DEBUG org.springframework.transaction.interceptor.Transa ctionInterceptor.doCloseTransactionAfterThrowing(2 81) - Invoking rollback for transaction on foo.Test.test due to throwable [java.lang.RuntimeException]
    2006-10-18 11:21:21,222 [main] DEBUG org.springframework.transaction.jta.JtaTransaction Manager.processRollback(588) - Participating transaction failed - marking existing transaction as rollback-only
    2006-10-18 11:21:21,222 [main] DEBUG org.springframework.transaction.jta.JtaTransaction Manager.doSetRollbackOnly(819) - Setting JTA transaction rollback-only
    2006-10-18 11:21:21,237 [main] DEBUG org.springframework.transaction.interceptor.RuleBa sedTransactionAttribute.rollbackOn(119) - Applying rules to determine whether transaction should rollback on java.lang.RuntimeException
    2006-10-18 11:21:21,237 [main] DEBUG org.springframework.transaction.interceptor.RuleBa sedTransactionAttribute.rollbackOn(137) - Winning rollback rule is: null
    2006-10-18 11:21:21,237 [main] DEBUG org.springframework.transaction.interceptor.RuleBa sedTransactionAttribute.rollbackOn(143) - No relevant rollback rule found: applying superclass default
    2006-10-18 11:21:21,237 [main] DEBUG org.springframework.transaction.interceptor.Transa ctionInterceptor.doCloseTransactionAfterThrowing(2 81) - Invoking rollback for transaction on foo.Test.test.test2 due to throwable [java.lang.RuntimeException]
    2006-10-18 11:21:21,237 [main] DEBUG org.springframework.transaction.jta.JtaTransaction Manager.triggerBeforeCompletion(673) - Triggering beforeCompletion synchronization
    2006-10-18 11:21:21,237 [main] DEBUG org.springframework.transaction.support.Transactio nSynchronizationManager.unbindResource(185) - Removed value [org.springframework.jdbc.datasource.ConnectionHold er@39474b] for key [org.apache.commons.dbcp.BasicDataSource@1696452] from thread [main]
    2006-10-18 11:21:21,237 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtil s.doReleaseConnection(285) - Returning JDBC Connection to DataSource
    2006-10-18 11:21:21,237 [main] DEBUG org.springframework.transaction.jta.JtaTransaction Manager.processRollback(581) - Initiating transaction rollback
    2006-10-18 11:21:21,253 [main] DEBUG org.springframework.transaction.jta.JtaTransaction Manager.triggerAfterCompletion(697) - Triggering afterCompletion synchronization
    2006-10-18 11:21:21,253 [main] DEBUG org.springframework.transaction.support.Transactio nSynchronizationManager.clearSynchronization(265) - Clearing transaction synchronization

    Thanks.

    Regards,
    Koala Lam

  6. #6
    Join Date
    Sep 2004
    Posts
    1,086

    Default

    What you are using is a XA driver, not a datasource. The datasource is DBCP and it's not XA. I suggest you download JOTM and give it a spin.

  7. #7
    Join Date
    Sep 2005
    Location
    Hong Kong, China
    Posts
    33

    Default

    Hi,

    Thanks for your information. However, what about if I want to use transaction manager from J2EE container (in my case, the WebLogic Server)? What I need is a XA DataSource, right ? So, where can I find an open source XA DataSource? Is XAPool from ObjectWeb is a good choice?

    Thanks a lot.

    Regards,
    Koala Lam

  8. #8
    Join Date
    Sep 2004
    Posts
    1,086

    Default

    XAPool is the implementation that's used by JOTM. Will it work with Weblogic JTA or not is hard to say.

  9. #9
    Join Date
    Sep 2005
    Location
    Hong Kong, China
    Posts
    33

    Default

    Hi,

    I have tried using XAPool with JTA looked up from WebLogic Server as well as JOTM. In both cases, I got the following strange behavior:

    2006-10-18 18:23:29,636 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - StandardPoolDataSource:getConnection
    2006-10-18 18:23:29,636 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - StandardPoolDataSource:getConnection must configure the pool...
    2006-10-18 18:23:29,636 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - StandardXADataSource:getXAConnection(user, password)
    2006-10-18 18:23:29,698 [main] ERROR org.enhydra.jdbc.xapool.error(55) - Error Exception in GenericPool:start java.sql.SQLException: Error trying to load driver: oracle.jdbc.xa.client.OracleXADataSource : null
    2006-10-18 18:23:29,698 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - StandardXADataSource:getXAConnection(user, password)
    2006-10-18 18:23:29,698 [main] ERROR org.enhydra.jdbc.xapool.error(55) - Error Exception in GenericPool:start java.sql.SQLException: Error trying to load driver: oracle.jdbc.xa.client.OracleXADataSource : null
    2006-10-18 18:23:29,698 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - GenericPool:start pool started
    2006-10-18 18:23:29,698 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - StandardPoolDataSource:getConnection pool config :
    GenericPool:
    num of element =<2>
    minSize =<2>
    maxSize =<2>
    lifeTime =<600000>
    ngeneration =<1>
    getLockedObjectCount() =<0>
    getUnlockedObjectCount() =<0>
    getDeadLockMaxWait() =<300000>
    getDeadLockRetryWait() =<10000>
    Unlocked pool:
    Locked pool:

    2006-10-18 18:23:29,698 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - StandardPoolDataSource:getConnection Try to give a connection (checkOut)
    2006-10-18 18:23:29,714 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - GenericPool:checkOut an object
    2006-10-18 18:23:29,714 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - GenericPool:checkOut UnlockedObjectCount=0
    2006-10-18 18:23:29,714 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - GenericPool:checkOut LockedObjectCount=0
    2006-10-18 18:23:29,714 [main] DEBUG org.enhydra.jdbc.xapool.debug(37) - GenericPool:checkOut count=2 maxSize=2
    2006-10-18 18:23:29,714 [main] INFO org.enhydra.jdbc.xapool.info(43) - GenericPool:checkOut waiting for an object :StandardXAPoolDataSource:
    StandardXADataSource:
    connection count=<0>
    number of dead connection=<0>
    dead lock max wait=<300000>
    dead lock retry wait=<10000>
    driver name=<oracle.jdbc.xa.client.OracleXADataSource>
    number of *free* connections=<0>
    max con=<0>
    min con=<50>
    prepared stmt cache size=<16>
    transaction manager=<org.objectweb.jotm.Current@13a34af>
    xid connection size=<0>
    StandardConnectionPoolDataSource:
    master prepared stmt cache size=<0>
    prepared stmt cache size =<16>
    StandardDataSource:
    driver=<null>
    url=<jdbc:oracle:thin:@192.168.88.229:1521:test>
    user=<null>
    CoreDataSource :
    debug =<false>
    description =<null>
    login time out =<60>
    user =<null>
    verbose =<false>
    StandardPoolDataSource:
    data source name=<null>
    jdbc test stmt=<null>
    user=<test>
    GenericPool:
    num of element =<2>
    minSize =<2>
    maxSize =<2>
    lifeTime =<600000>
    ngeneration =<1>
    getLockedObjectCount() =<0>
    getUnlockedObjectCount() =<0>
    getDeadLockMaxWait() =<300000>
    getDeadLockRetryWait() =<10000>
    Unlocked pool:
    Locked pool:

    2006-10-18 18:23:39,714 [main] INFO org.enhydra.jdbc.xapool.info(43) - GenericPool:checkOut waiting for an object :StandardXAPoolDataSource:
    StandardXADataSource:
    connection count=<0>
    number of dead connection=<0>
    dead lock max wait=<300000>
    dead lock retry wait=<10000>
    driver name=<oracle.jdbc.xa.client.OracleXADataSource>
    number of *free* connections=<0>
    max con=<0>
    min con=<50>
    prepared stmt cache size=<16>
    transaction manager=<org.objectweb.jotm.Current@13a34af>
    xid connection size=<0>
    StandardConnectionPoolDataSource:
    master prepared stmt cache size=<0>
    prepared stmt cache size =<16>
    StandardDataSource:
    driver=<null>
    url=<jdbc:oracle:thin:@192.168.88.229:1521:bmtp3>
    user=<null>
    CoreDataSource :
    debug =<false>
    description =<null>
    login time out =<60>
    user =<null>
    verbose =<false>
    StandardPoolDataSource:
    data source name=<null>
    jdbc test stmt=<null>
    user=<test>
    GenericPool:
    num of element =<2>
    minSize =<2>
    maxSize =<2>
    lifeTime =<600000>
    ngeneration =<1>
    getLockedObjectCount() =<0>
    getUnlockedObjectCount() =<0>
    getDeadLockMaxWait() =<300000>
    getDeadLockRetryWait() =<10000>
    Unlocked pool:
    Locked pool:

    And my program turns out to be never end. Shown below is the new configuration:

    <bean id="jotm" name="jtaTransactionManager" class="org.springframework.transaction.jta.JotmFac toryBean">
    </bean>

    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager" lazy-init="false">
    <property name="userTransaction"><ref local="jotm"/></property>
    </bean>

    <bean id="innerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSou rce" destroy-method="shutdown">
    <property name="transactionManager" ref="jotm"/>
    <property name="driverName">
    <value>${jdbc.driverClassName}</value>
    </property>
    <property name="url">
    <value>${jdbc.url}</value>
    </property>
    </bean>

    <bean id="dataSource_XAPool"
    class="org.enhydra.jdbc.pool.StandardXAPoolDataSou rce"
    destroy-method="shutdown">
    <property name="dataSource" ref="innerDataSource"/>
    <property name="user">
    <value>${jdbc.username}</value>
    </property>
    <property name="password">
    <value>${jdbc.password}</value>
    </property>
    <property name="maxSize" value="2"/>
    </bean>

    Still, I am using XA JDBC driver "oracle.jdbc.xa.client.OracleXADataSource".

    Thanks a lot.

    Regards,
    Koala Lam

  10. #10
    Join Date
    Sep 2004
    Posts
    1,086

    Default

    No idea really, but the error seems to be:

    2006-10-18 18:23:29,698 [main] ERROR org.enhydra.jdbc.xapool.error(55) - Error Exception in GenericPool:start java.sql.SQLException: Error trying to load driver: oracle.jdbc.xa.client.OracleXADataSource : null

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •