Announcement Announcement Module
Collapse
No announcement yet.
Standalone JTA (Bitronix) + JPA (XA) JDBC + JPA JMS MDP (XA) ActiveMQ Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Standalone JTA (Bitronix) + JPA (XA) JDBC + JPA JMS MDP (XA) ActiveMQ

    Attached is standalone code that sets up and tests XA 2-phase commit on two transactional resources through JTA (using Bitronix Transaction Manager).

    The two resources are (a) an embedded Derby database accessed via an XA aware JDBC connection (b) an embedded ActiveMQ JMS queue accessed via Spring Message Driven Pojo (MDP).

    The library versions used are:

    * org.codehaus.btm:btm:1.3
    * org.apache.derby:derby:10.4.2.0
    * org.springframework:spring:2.5.6
    * activemq:activemq-core:3.2.4

    The spring configuration is:

    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="ht tp://ww w.springframework.org/schema/beans"
    	xmlns:xsi="ht tp://ww w.w3.org/2001/XMLSchema-instance" xmlns:tx="ht tp://ww w.springframework.org/schema/tx"
    	xmlns:p="ht tp://ww w.springframework.org/schema/p" xmlns:util="ht tp://ww w.springframework.org/schema/util"
    	xsi:schemaLocation="
    	ht tp://ww w.springframework.org/schema/beans ht tp://ww w.springframework.org/schema/beans/spring-beans.xsd
        ht tp://ww w.springframework.org/schema/tx ht tp://ww w.springframework.org/schema/tx/spring-tx.xsd
        ht tp://w ww.springframework.org/schema/util ht tp://w ww.springframework.org/schema/util/spring-util-2.0.xsd
    	">
    	
    	<description>
    	This file defines a Bitronix Transaction Manager (BTM), a Spring Message Driven Pojo (MDP), and a JDBC DAO. 
    	</description>
    	
    	<!-- Bitronix Transaction Manager embedded configuration -->
    	<bean id="btmConfig" factory-method="getConfiguration"
    		class="bitronix.tm.TransactionManagerServices">
    		<property name="serverId" value="spring-btm" />
    	</bean>
    
    	<!-- Create the BTM transaction manager -->
    	<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
    		class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig,xaDataSource"
    		destroy-method="shutdown" />
    
    	<!-- Spring JtaTransactionManager -->
    	<bean id="jtaTransactionManager"
    		class="org.springframework.transaction.jta.JtaTransactionManager">
    		<property name="transactionManager" ref="BitronixTransactionManager" />
    		<property name="userTransaction" ref="BitronixTransactionManager" />
    	</bean>
    
    	<!-- XA DataSource -->
    	<bean id="xaDataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource"
    		init-method="init" destroy-method="close">
    		<property name="className" value="org.apache.derby.jdbc.EmbeddedXADataSource" />
    		<property name="uniqueName" value="derby1" />
    		<property name="minPoolSize" value="0" />
    		<property name="maxPoolSize" value="3" />
    		<property name="driverProperties">
    			<props>
    				<prop key="databaseName">derbydb</prop>
    				<prop key="createDatabase">create</prop>
    			</props>
    		</property>
    	</bean>
    
    	<!-- Raw untransactional DAO  -->
    	<bean id="messageSequenceDaoImpl" class="com.acme.springjta.jdbc.MessageSequenceDaoImpl">
    		<property name="dataSource" ref="xaDataSource" />
    	</bean>
    	
    	<!-- Transactional wrapper of the DAO -->
    	<bean id="messageSequenceDAO"
    		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="jtaTransactionManager" />
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRED, -Exception
    				</prop>
    			</props>
    		</property>
    		<property name="target" ref="messageSequenceDaoImpl" />
    	</bean>
    
    	<!-- XA JMS Connection Factory -->
    	<bean id="xaJmsConnectionFactory" class="bitronix.tm.resource.jms.PoolingConnectionFactory"
    		init-method="init" destroy-method="close">
    		<property name="className" value="org.activemq.ActiveMQXAConnectionFactory" />
    		<property name="uniqueName" value="activemq" />
    		<property name="minPoolSize" value="1" />
    <!-- you would want a bigger pool and look to tune the number of threads working with ActiveMQ! -->
    		<property name="maxPoolSize" value="1" />
    		<property name="allowLocalTransactions" value="true" />
    		<property name="user" value="user" />
    		<property name="password" value="password" />
    		<property name="driverProperties">
    			<props>
    				<prop key="brokerURL">vm://localhost</prop>
    			</props>
    		</property>
    	</bean>
    
    	<!-- JMS Destination -->
    	<bean id="destination" class="org.activemq.message.ActiveMQQueue">
    		<constructor-arg value="test.queue" />
    	</bean>
    
    	<!-- JMS Template for sending messages -->
    	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    		<property name="connectionFactory" ref="xaJmsConnectionFactory" />
    		<property name="defaultDestination" ref="destination" />
    	</bean>
    
    	<!-- Service for sending JMS messages -->
    	<bean id="defaultTextMessageSender" class="com.acme.springjta.mdp.DefaultTextMessageSender">
    		<property name="jmsTemplate" ref="jmsTemplate" />
    	</bean>
    
    	<!-- Transactional wrapper of the service for sending JMS message -->
    	<bean id="textMessageSender"
    		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="jtaTransactionManager" />
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRED, -Exception
    				</prop>
    			</props>
    		</property>
    		<property name="target" ref="defaultTextMessageSender" />
    	</bean>
    
    	<!-- Our Message Driven POJO. Normally such a MDP would have an injected DataSource or injected DAO -->
    	<bean id="textMessageDelegate" class="com.acme.springjta.mdp.DefaultTextMessageDelegate" />
    
    	<!-- JMS Listener Delegates to our Message Driven POJO -->
    	<bean id="messageListener"
    		class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
    		<constructor-arg ref="textMessageDelegate" />
    		<property name="defaultListenerMethod" value="receive" />
    		<!-- we don't want automatic message context extraction -->
    		<property name="messageConverter">
    			<null />
    		</property>
    	</bean>
    
    	<!-- JMS Container For Receiving Messages Under XA -->
    	<bean id="jmsContainer"
    		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    		<property name="connectionFactory" ref="xaJmsConnectionFactory" />
    		<property name="destination" ref="destination" />
    		<property name="messageListener" ref="messageListener" />
    		<property name="transactionManager" ref="jtaTransactionManager" />
    	</bean>
    </beans>
    The code is built by maven and only the "test" goal is implemented. To build and run the sample:

    1) download and extract a maven2 distribution
    2) set an environment variable "MAVEN_HOME" to name the absolute path of the unzipped maven2 folder
    3) set an environment variable "JAVA_HOME" to name the absolute path of the top level of your Java1.5+ JDK folder
    4) prepend the "bin" subfolders of both "MAVEN_HOME" and "JAVA_HOME" to your "PATH"
    5) open up a shell (cmd.exe on windows else bash on un1x) and "cd" into the folder of the extracted sample app code
    6) run the command "mvn test". maven should pull down all dependent jar files and run the unit tests.

    Alternatively if you are using eclipse you can simply install the m2eclipse plug-in and just import the extracted zip as a project in your workspace. The simply right click on the project and choose "Run As..." > "maven test".

  • #2
    Standalone JTA (Bitronix) + JPA Hibernate + JPA MDP (XA) ActiveMQ

    As an enhancement to the sample code above attached is addition code that tests Hibernate as a substitute to the JDBC DAO.

    Libraries used:

    * org.hibernate:hibernate:3.2.6.ga

    The spring configuration used is as follows:

    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="ht tp://ww w.springframework.org/schema/beans"
    	xmlns:xsi="h ttp://ww w.w3.org/2001/XMLSchema-instance" xmlns:tx="ht tp://ww w.springframework.org/schema/tx"
    	xmlns:p="ht tp://ww w.springframework.org/schema/p" xmlns:util="ht tp://ww w.springframework.org/schema/util"
    	xsi:schemaLocation="
    	ht tp://w ww.springframework.org/schema/beans ht tp://ww w.springframework.org/schema/beans/spring-beans.xsd
        ht tp://w ww.springframework.org/schema/tx ht tp://ww w.springframework.org/schema/tx/spring-tx.xsd
        ht tp://w ww.springframework.org/schema/util ht tp://ww w.springframework.org/schema/util/spring-util-2.0.xsd
    	">
    	
    	<description>
    	This file defines a Bitronix Transaction Manager (BTM) a Spring Message 
    	Driven Pojo (MDP) and a Hibernate DAO. 
    	</description>
    
    	<!-- Bitronix Transaction Manager embedded configuration -->
    	<bean id="btmConfig" factory-method="getConfiguration"
    		class="bitronix.tm.TransactionManagerServices">
    		<property name="serverId" value="spring-btm" />
    	</bean>
    
    	<!-- create BTM transaction manager -->
    	<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
    		class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig"
    		destroy-method="shutdown" />
    
    	<!-- Spring JtaTransactionManager -->
    	<bean id="jtaTransactionManager"
    		class="org.springframework.transaction.jta.JtaTransactionManager">
    		<property name="transactionManager" ref="BitronixTransactionManager" />
    		<property name="userTransaction" ref="BitronixTransactionManager" />
    	</bean>
    
    	<!-- XA JMS Connection Factory -->
    	<bean id="xaJmsConnectionFactory" class="bitronix.tm.resource.jms.PoolingConnectionFactory"
    		init-method="init" destroy-method="close">
    		<property name="className" value="org.activemq.ActiveMQXAConnectionFactory" />
    		<property name="uniqueName" value="activemq" />
    		<property name="minPoolSize" value="1" />
    		<property name="maxPoolSize" value="1" />
    		<property name="allowLocalTransactions" value="true" />
    		<property name="user" value="user" />
    		<property name="password" value="password" />
    		<property name="driverProperties">
    			<props>
    				<prop key="brokerURL">vm://localhost</prop>
    			</props>
    		</property>
    	</bean>
    	
    	<!-- Raw DataSource managed by Hibernate -->
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName">
                <value>org.apache.derby.jdbc.EmbeddedDriver</value>
            </property>
            <property name="url">
                <value>jdbc:derby:derbydb2;create=true</value>  
            </property>
        </bean>
    
    	<!-- JTA (Bitronix Aware) Hibernate Session factory. The code for BTMTransactionManagerLookup can 
    	be found at jboss.org   -->
    	<bean id="hibernateSessionFactory"
    		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="mappingResources">
    			<list>
    				<value>HibernateMappedObject.hbm.xml</value>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.show_sql">true</prop>
    				<prop key="hibernate.use_outer_join">true</prop>
    				<prop key="hibernate.hbm2ddl.auto">update</prop>
    				<prop key="hibernate.cache.use_query_cache">false</prop>
    				<prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
    				<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
    				<prop key="hibernate.cache.use_second_level_cache">false</prop>
    				<!-- JTA stuff  -->
    				<prop key="hibernate.connection.release_mode">after_statement</prop>
    				<prop key="hibernate.current_session_context_class">jta</prop>
    				<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup</prop>
    			</props>
    		</property>
    	</bean>
    	
    	<!-- Spring Hibernate helper -->
    	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    		<property name="sessionFactory" ref="hibernateSessionFactory" />
    	</bean>
    	
    	<!-- None transactional hibernate backed DAO  -->
    	<bean id="rawHibernateDao" class="com.acme.springjta.hibernate.HibernateObjectDaoImpl">
    		<property name="hibernateTemplate" ref="hibernateTemplate" />
    	</bean>
    	
    	<!-- JTA trasactional wrapper to the hibernate backed DAO  -->
    	<bean id="hibernateDao"
    		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="jtaTransactionManager" />
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRED, -Exception
    				</prop>
    			</props>
    		</property>
    		<property name="target" ref="rawHibernateDao" />
    	</bean>
    
    	<!-- JMS Destination -->
    	<bean id="destination" class="org.activemq.message.ActiveMQQueue">
    		<constructor-arg value="test.queue" />
    	</bean>
    
    	<!-- JMS Template for sending messages -->
    	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    		<property name="connectionFactory" ref="xaJmsConnectionFactory" />
    		<property name="defaultDestination" ref="destination" />
    	</bean>
    
    	<!-- Service for sending JMS messages -->
    	<bean id="defaultTextMessageSender" class="com.acme.springjta.mdp.DefaultTextMessageSender">
    		<property name="jmsTemplate" ref="jmsTemplate" />
    	</bean>
    
    	<!-- Transactional wrapper of the service for sending JMS message -->
    	<bean id="textMessageSender"
    		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="jtaTransactionManager" />
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRED, -Exception
    				</prop>
    			</props>
    		</property>
    		<property name="target" ref="defaultTextMessageSender" />
    	</bean>
    
    	<!-- Our Message Driven POJO - In JUnit I happen to be downcasting this to the concrete class and 
    	registering a callback that uses the Hibernate DAO. More normally you could use an MDP that has 
    	the DAO injected into it to do data access -->
    	<bean id="textMessageDelegate" class="com.acme.springjta.mdp.DefaultTextMessageDelegate" />
    
    	<!-- JMS Listener Delegates to our Message Driven POJO -->
    	<bean id="messageListener"
    		class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
    		<constructor-arg ref="textMessageDelegate" />
    		<property name="defaultListenerMethod" value="receive" />
    		<!-- we don't want automatic message context extraction -->
    		<property name="messageConverter">
    			<null />
    		</property>
    	</bean>
    
    	<!-- JMS Container For Receiving Messages Under XA -->
    	<bean id="jmsContainer"
    		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    		<property name="connectionFactory" ref="xaJmsConnectionFactory" />
    		<property name="destination" ref="destination" />
    		<property name="messageListener" ref="messageListener" />
    		<property name="transactionManager" ref="jtaTransactionManager" />
    	</bean>
    
    </beans>

    Comment


    • #3
      Apologies that the command line build was broken due to missing jms dependency that was not an issue within eclipse (damb point and click monkey...). The pom.xml below builds on the command line with maven209

      It has been pointed out to me that I am seeing hibernate 3.2.6.ga on the central maven repository yet 3.3.1.GA is the latest at ht tp://repository.jboss.c om/maven2/org/hibernate/hibernate/. Spending a little while trying to get that working is turning into a bit of a headache. Can anyone please enlighten me as to how to get hibernate3.3.1.GA working without hacking the .m2/settings.xml file? Thanks!

      Code:
      <project xmlns="ht tp://maven.apache.o rg/POM/4.0.0" xmlns:xsi="ht tp://ww  w.w3.org/2001/XMLSchema-instance"
      	xsi:schemaLocation="ht tp://maven.apache.org/POM/4.0.0 ht tp://maven.apache.org/maven-v4_0_0.xsd">
      	<modelVersion>4.0.0</modelVersion>
      	<groupId>com.acme</groupId>
      	<artifactId>springjta</artifactId>
      	<packaging>war</packaging>
      	<version>0.0.1-SNAPSHOT</version>
      	<name>springjta Maven Webapp</name>
      	<url>ht tp://maven.apache.org</url>
      	<properties>
      		<junit.version>3.8.2</junit.version>
      		<spring.version>2.5.6</spring.version>
      		<derby.version>10.4.2.0</derby.version>
      		<hibernate.version>3.2.6.ga</hibernate.version>
      		<zk.version>3.5.1</zk.version>
      		<log4j.version>1.2.15</log4j.version>
      		<btm.version>1.3.2</btm.version>
      		<activemq.version>3.2.4</activemq.version>
      		<dbcp.version>1.2.2</dbcp.version>
      		<jms.version>1.1</jms.version>
      	</properties>
      	<dependencies>
      		<dependency>
      			<groupId>javax.jms</groupId>
      			<artifactId>jms</artifactId>
      			<version>${jms.version}</version>
      			<scope>compile</scope>
      		</dependency>
      		<dependency>
      			<groupId>org.apache.derby</groupId>
      			<artifactId>derby</artifactId>
      			<version>${derby.version}</version>
      			<scope>runtime</scope>
      		</dependency>
      		<dependency>
      			<groupId>junit</groupId>
      			<artifactId>junit</artifactId>
      			<version>${junit.version}</version>
      			<scope>test</scope>
      		</dependency>
      		<dependency>
      			<groupId>org.codehaus.btm</groupId>
      			<artifactId>btm</artifactId>
      			<version>${btm.version}</version>
      			<scope>runtime</scope>
      		</dependency>
      		<dependency>
      			<!-- required indirecty by BTM but not used  -->
      			<groupId>org.slf4j</groupId>
      			<artifactId>slf4j-jdk14</artifactId>
      			<version>1.5.2</version>
      			<scope>runtime</scope>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework</groupId>
      			<artifactId>spring</artifactId>
      			<version>${spring.version}</version>
      			<scope>compile</scope>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework</groupId>
      			<artifactId>spring-test</artifactId>
      			<version>${spring.version}</version>
      			<scope>test</scope>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework</groupId>
      			<artifactId>spring-orm</artifactId>
      			<version>${spring.version}</version>
      			<scope>compile</scope>
      		</dependency>
      		<dependency>
      			<groupId>log4j</groupId>
      			<artifactId>log4j</artifactId>
      			<version>${log4j.version}</version>
      			<scope>compile</scope>
      			<exclusions>
      				<exclusion>
      					<groupId>com.sun.jmx</groupId>
      					<artifactId>jmxri</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>com.sun.jdmk</groupId>
      					<artifactId>jmxtools</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>javax.jms</groupId>
      					<artifactId>jms</artifactId>
      				</exclusion>
      			</exclusions>
      		</dependency>
      		<dependency>
      			<groupId>activemq</groupId>
      			<artifactId>activemq-core</artifactId>
      			<version>${activemq.version}</version>
      			<scope>runtime</scope>
      			<exclusions>
      				<exclusion>
      					<groupId>net.java.dev.javacc</groupId>
      					<artifactId>javacc</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>xmlbeans</groupId>
      					<artifactId>xbean</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>xmlbeans</groupId>
      					<artifactId>xmlbeans-jsr173-api</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>activecluster</groupId>
      					<artifactId>activecluster</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>activeio</groupId>
      					<artifactId>activeio</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>activemq</groupId>
      					<artifactId>smack</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>activemq</groupId>
      					<artifactId>smackx</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>activesoap</groupId>
      					<artifactId>jax</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>axion</groupId>
      					<artifactId>axion</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>cglib</groupId>
      					<artifactId>cgli</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>commons-collections</groupId>
      					<artifactId>commons-collections</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>commons-dbcp</groupId>
      					<artifactId>commons-dbcp</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>commons-logging</groupId>
      					<artifactId>commons-logging</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>commons-pool</groupId>
      					<artifactId>commons-pool</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>activemq</groupId>
      					<artifactId>activemq-core-test</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>commons-primitives</groupId>
      					<artifactId>commons-primitives</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>howl</groupId>
      					<artifactId>how-logger</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>hsqldb</groupId>
      					<artifactId>hsqldb</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>jmock</groupId>
      					<artifactId>jmock</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>junit</groupId>
      					<artifactId>junit</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>log4j</groupId>
      					<artifactId>log4j</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>org.apache.derby</groupId>
      					<artifactId>derby</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>regexp</groupId>
      					<artifactId>regexp</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>stax</groupId>
      					<artifactId>stax</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>stax</groupId>
      					<artifactId>stax</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>xalan</groupId>
      					<artifactId>xalan</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>xmlbeans</groupId>
      					<artifactId>xbean_xpath</artifactId>
      				</exclusion>
      				<exclusion>
      					<groupId>xmlbeans</groupId>
      					<artifactId>xmlpublic</artifactId>
      				</exclusion>
      			</exclusions>
      		</dependency>
      		<dependency>
      			<groupId>org.hibernate</groupId>
      			<artifactId>hibernate</artifactId>
      			<version>${hibernate.version}</version>
      			<scope>runtime</scope>
      			<exclusions>
      				<exclusion>
      					<groupId>javax.transaction</groupId>
      					<artifactId>jta</artifactId>
      				</exclusion>
      			</exclusions>
      		</dependency>
      		<dependency>
      			<groupId>commons-dbcp</groupId>
      			<artifactId>commons-dbcp</artifactId>
      			<version>${dbcp.version}</version>
      			<scope>runtime</scope>
      		</dependency>
      	</dependencies>
      	<build>
      		<finalName>springjta</finalName>
      		<plugins>
      			<plugin>
      				<groupId>org.apache.maven.plugins</groupId>
      				<artifactId>maven-compiler-plugin</artifactId>
      				<configuration>
      					<source>1.5</source>
      					<target>1.5</target>
      				</configuration>
      			</plugin>
      		</plugins>
      	</build>
      </project>

      Comment


      • #4
        This can't work...

        Hi,

        The datasource is not JTA-enabled:

        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName">
        <value>org.apache.derby.jdbc.EmbeddedDriver</value>
        </property>
        <property name="url">
        <value>jdbc:derby:derbydb2;create=true</value>
        </property>
        </bean>

        So unless I missed something, there is no JTA/XA access to the JDBC... Or: rollback on the JTA transaction will not rollback the database.

        Interesting sample though. Let me check if we can post the equivalent config for Atomikos TransactionsEssentials too...

        Best
        Guy

        http://www.atomikos.com
        Connection pooling and transaction management for J2SE
        J2EE without application server

        Comment


        • #5
          two different examples: hiberntate or JDBC (with junits test prooving tx rollback)

          Guy,

          If you read this topic chronologically you have replied to my first post but cut-and-pasted configuration from a later post demonstrating something different to the post that you have actually replied to.

          If you look again at the post that you actually replied to you will see a bean called "xaDataSource" which is the thing that you thought was missing.

          thx

          Simon

          Comment


          • #6
            run the tests for the JDBC DOA or the Hibernate DOA seperately

            If you unzip my hibernate backed MDP example over the original zip file (the raw JDBC backed MDP example) you may find that the original test using the JDBC DAO cannot be run consecutively with the test that uses the Hibernate DAO.

            To work around this simply rename one or the other test java files (else use your IDE to only run one of the tests at a time, else pass maven an argument telling it the individual test to run, else patch my junit code to use two separate application contexts and/or classloaders (and post your patch to this thread)).

            Comment


            • #7
              I just used the zip download

              Hi,

              Originally posted by simon1905 View Post
              Guy,

              If you read this topic chronologically you have replied to my first post but cut-and-pasted configuration from a later post demonstrating something different to the post that you have actually replied to.
              Simon
              I just downloaded the sample and looked at the config.

              Best
              Guy

              Comment


              • #8
                could you please post an atomikos version of the configs?

                [Post title is out of date - I had missed Guys offer to post some Atomikos configuratoins.]

                Guy,

                Thanks for your offer to post Atomikos configurations for the code. I feel that would complete the picture with regards to showing how Spring lets you easily switch vendors. For my actual system I intend to put the TM+XAResource config in a separate file, then use a stand-alone JTA configuration for the unit tests with embedded resource, but in production use a config that uses the spring support of the container TM + JNDI lookups for the XA aware datasources (oracle and ibm mq). I think that running a lightweight TM in JUnit to test that your error handling is working is definitely a big productivity advantage compared to testing in-container.

                I noted the lack of working examples of standaloneJTA+MDPs+ORM last week when I was struggling to get Atomikos+MPDs+OpenJPA working. I think that my error at the time might have been trying to use an XA JDBC pool with ORM whilst telling the ORM framework to be the XA aware resource. My tests show that you should use a vanilla JDBC pool (the one you posted a fragment of) with the JTA aware ORM framework, such that you have only one XA aware component for the database (not two that may conflict).

                If you feel like contributing (some more) and have some time could you post an example like mine demonstrates using a OpenJPA backed DAO inside an MDP with rollback (with Atomikos of course )? Then you would be helping me out as a potential Atomikos customer by helping me out with my original problem (that got me out here in the first place).

                Thanks,

                Simon
                Last edited by simon1905; Dec 8th, 2008, 04:45 PM. Reason: just re-read that I had missed Guys offer to contribute configurations

                Comment


                • #9
                  Atomikos config

                  Hi,

                  We can work on the equivalent Atomikos config, however in exchange I would like to ask:

                  1-that we can use the example in the Atomikos wiki
                  2-that you send us the closest thing to a working config you have already (or is that the zip file in this thread?)

                  Best
                  Guy

                  Comment


                  • #10
                    Originally posted by GuyPardon View Post
                    1-that we can use the example in the Atomikos wiki
                    Sure. The code and config is public domain. I published it for people to do what they wish and copy and adapt as they wish with no warranty. One condition to you using them I give below.

                    Originally posted by GuyPardon View Post
                    2-that you send us the closest thing to a working config you have already (or is that the zip file in this thread?)
                    Attached is a latest copy with WORKING JUNIT tests exactly as all the other post code comes with working junit test that show, well, that it works (thats what they are there for, right?)

                    If there are flaws in my test method then my condition for you publishing the configurations on your site is that you yourself actively try to fix up the JUnit tests so that they correctly test things, if indeed there is any issue with them, which I have no reason to think there is, and publish your updated JUnit tests and any fixes to the configuration here on this topic.

                    Simon

                    Comment


                    • #11
                      Certified tests you mean :-)

                      Hi,

                      OK we will check your tests - and if time allows we will even run our application certification program on the test suite - courtesy of the house :-)

                      Expect something in the next few weeks (hopefully). End of year is always extra busy here... Poll me if needed.

                      Comment


                      • #12
                        Final: Standalone JTA (Bitronix) + JDBC DAO / Hibernate DAO + JMS MDP ActiveMQ

                        Attached is a final version of the example application containing the example configurations. It contains two different configurations - one using a JDBC DOA and one using a Hibernate DOA.

                        It has been reviewed by the very new user friendly Bitronix folks. Ludovic Orban of the Bitronix project was very kind in reviewing the test methodology. He was also very patient and encouraging in explaining the nuances. He pointed out that yes the tests of rollback worked when throwing an exception in the original hibernate example, but because the datasource in the original hibernate configuration was not XA aware, there would be issues with recovery of the state of the system in the case of a crash. So it was a case of close but no cigar - it tested as safe from code throwing exceptions but not fully XA if one of the (possibly) distributed resources crashed.

                        Other notes:

                        1) bumped to the latest hibernate
                        2) i had typo'ed the original title - i am using the native hibernate API not the hibernate JPA entitymanager
                        3) fixed the junit tests to run the tests in a fresh application contexts such that all tests run sequentially okay in the one jvm
                        4) downgraded the project output from war to jar

                        Comment


                        • #13
                          For springjta1.0.zip, test with hibernate + JMS, I found that you are using BasicDataSource from DBCP but not PoolingDataSource from BTM.

                          could you please explain the purpose of test-raw-pool-context.xml?

                          Comment


                          • #14
                            Originally posted by kelvinlaw View Post
                            For springjta1.0.zip, test with hibernate + JMS, I found that you are using BasicDataSource from DBCP but not PoolingDataSource from BTM.
                            could you please explain the purpose of test-raw-pool-context.xml?
                            Kelvin,

                            I should have removed the raw pool test file. The actual context files to look at are in src/main/resources and those use the btm PoolingDataSource as expected. I have repackaged the zip file removing that spurious file. I have also added a new test and context file that tries out the Bitronix last resource commit feature for a non-xa-jdbc resource using hypersonic db. I have left the appropriate comment in the context file that there are caveats when using the last resource commit gambit.

                            Simon

                            Comment


                            • #15
                              An example of such configuration with JPA on top of Hibernate would be nice as well.

                              Comment

                              Working...
                              X