Atomikos Forum |
|
Hi;
I integrated Atomikos, Hibernate and ActiveMQ using Spring but when I rollback a Hibernate action it is not work but jms rollback works. ============================================================== this is my XML file: [code] <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <!-- <bean id="localLogAdministrator" class="com.atomikos.icatch.admin.imp.LocalLogAdministrator" />--> <bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp" init-method="init" destroy-method="shutdownForce"> <constructor-arg> <props> <prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory</prop> <prop key="com.atomikos.icatch.tm_unique_name">fered</prop> <prop key="com.atomikos.icatch.log_base_name">fered</prop> <prop key="com.atomikos.icatch.log_base_dir">/tmp/</prop> <!-- DEBUGGING PROPERTIES --> <prop key="com.atomikos.icatch.output_dir">/tmp/</prop> <prop key="com.atomikos.icatch.console_file_name">atomikos.log</prop> <prop key="com.atomikos.icatch.console_log_level">DEBUG</prop> <prop key="com.atomikos.icatch.threaded_2pc">true</prop> </props> </constructor-arg> </bean> <!-- Construct Atomikos UserTransactionManager,needed to configure Spring --> <bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close" depends-on="userTransactionService"> <!-- IMPORTANT: disable startup because the userTransactionService above does this --> <property name="startupTransactionService" value="false" /> <!-- when close is called,should we force transactions to terminate or not? --> <property name="forceShutdown" value="true" /> </bean> <!--Also use Atomikos UserTransactionImp,needed to configure Spring--> <bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" depends-on="userTransactionService"> <property name="transactionTimeout" value="300" /> </bean> <!--Configure the Spring framework to use JTA transactions from Atomikos--> <bean id="JtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="userTransactionService"> <property name="transactionManager" ref="AtomikosTransactionManager" /> <property name="userTransaction" ref="AtomikosUserTransaction" /> </bean> <!-- configure Hibernate to use the Atomikos JTA and datasource for transaction control --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- add the mapped resources (hbm files) of your application --> <property name="mappingResources"> <list> <value>Account.hbm.xml</value> </list> </property> <!-- make sure that hibernate uses the Atomikos datasource (JTA enabled)! --> <property name="dataSource"> <ref bean="datasource" /> </property> <!-- configure hibernate to use Atomikos TransactionsEssentials --> <property name="hibernateProperties"> <props> <prop key="hibernate.transaction.factory_class"> com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory <!-- com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory org.hibernate.transaction.JTATransactionFactory org.hibernate.transaction.JDBCTransactionFactory --> </prop> <prop key="hibernate.transaction.manager_lookup_class"> com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup </prop> <!-- for hibernate 2, use the following: <prop key="hibernate.transaction.manager_lookup_class"> com.atomikos.icatch.jta.hibernate.TransactionManagerLookup </prop> --> <!-- add any other hibernate properties you need --> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <!-- Enable Hibernate's automatic session context management --> <prop key="hibernate.current_session_context_class">jta</prop> <!-- Disable the second-level cache --> <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop> <!-- Echo all executed SQL to stdout --> <prop key="hibernate.show_sql">true</prop> <!-- Drop and re-create the database schema on startup --> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> </props> </property> </bean> <!-- configure the Spring hibernate template with the session factory from above --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean> <!-- a class that implements javax.jms.MessageListener --> <bean id="MessageListener" class="TextOutputMessageListener" /> <!-- Configure the JMS template used to send messages --> <bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="ConnectionFactory" /> <property name="sessionTransacted" value="true" /> </bean> <!-- create real business object, this is your own implementation --> <bean id="RealAccountFacade" class="AccountFacade"> <property name="jmsTemplate" ref="JmsTemplate" /> <property name="queue" ref="Queue" /> </bean> <!-- wrap real business object with a spring-generated JTA proxy this is the only object that need to be obtained from the ApplicationContext --> <bean id="AccountFacade" 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="RealAccountFacade" /> </bean> <bean id="RealAccountManager" class="AccountManager"> <property name="hibernateTemplate" ref="hibernateTemplate" /> </bean> <bean id="AccountManager" 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="RealAccountManager" /> </bean> <!-- configure an Atomikos JTA-aware datasource --> <bean id="datasource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <!-- set an arbitrary but unique name for the datasource --> <property name="uniqueResourceName"> <value>XADBMS</value> </property> <!-- set the underlying driver class to use, in this example case we use Oracle --> <property name="xaDataSourceClassName"> <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value> </property> <!-- set the driver-specific XADataSource properties (check your driver docs for more info) --> <property name="xaProperties"> <props> <prop key="user">fered</prop> <prop key="password">123456</prop> <prop key="URL">jdbc:mysql://localhost:3306/AtomikosHibernate</prop> </props> </property> <!-- how many connections in the pool? --> <property name="poolSize" value="1" /> </bean> <!-- Allows us to set properties used as ant-like variables ${...} --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="properties"> <props> <prop key="poolSize">1</prop> <prop key="outboundQueueName">outQ</prop> <prop key="AckQueueName">inQ</prop> </props> </property> </bean> <bean id="xaFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <!-- Configure the JMS connector; call init to register for recovery! --> <bean id="RealConnectionFactory" class="com.atomikos.jms.QueueConnectionFactoryBean" init-method="init"> <property name="resourceName" value="amq1" /> <property name="xaQueueConnectionFactory" ref="xaFactory" /> </bean> <bean id="ConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <property name="targetConnectionFactory" ref="RealConnectionFactory" /> </bean> <bean id="Queue" class="org.apache.activemq.command.ActiveMQQueue"> <property name="physicalName" value="${outboundQueueName}" /> </bean> </beans> [/code] ============================================================= and this is main: [code] public static void main(String[] args) throws JMSException, InterruptedException, NotSupportedException, SystemException, IllegalStateException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException { AccountFacade accountFacade = (AccountFacade) ContextManager.getBean("AccountFacade"); AccountManager accountManager = (AccountManager) ContextManager.getBean("AccountManager"); while (true) { JtaTransactionManager jtaTransactionManager = (JtaTransactionManager) ContextManager.getBean("JtaTransactionManager"); jtaTransactionManager.getUserTransaction().begin(); Account account = accountFacade.getAcount(); System.out.println(account.getAccountNo()); accountManager.creatAndStoreAccount(account); System.out.println("rollback"); jtaTransactionManager.getUserTransaction().rollback(); Thread.sleep(1000); } } [/code] ============================================================ other classes: [code] public class AccountFacade { private JmsTemplate jmsTemplate; private Queue queue; public AccountFacade() { } public void setJmsTemplate(JmsTemplate jmsTemplate) { this.jmsTemplate = jmsTemplate; } public void setQueue(Queue queue) { this.queue = queue; } public Account getAcount() throws JMSException { Message message = jmsTemplate.receive(queue); if (message instanceof ObjectMessage) { Account account = (Account)( (ObjectMessage) message).getObject(); return account; } return null; } } public class AccountManager { HibernateTemplate hibernateTemplate; public AccountManager() { super(); } public HibernateTemplate getHibernateTemplate() { return hibernateTemplate; } public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; this.hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_AUTO); } public void creatAndStoreAccount(final Account account) { hibernateTemplate.save(account); } } [/code] after rollback, jms queue, requeue the received message but the saved object does not remove from database and hibernate does not rollback save. what's the problem? thanks. |