I use Spring JtaTransactionManager to manager the global transaction, BTM(Bitronix) as the JTA implementation, MySQL as the XA datasource, Hibernate as the JPA implementation.
I use programmable transactionManager config and config datasource and transaction in Spring applicationContext.xml:
I config persistence-unit for Hibernate/JPA in another persistence.xml.Code:<bean id="dataSource1" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close"> <property name="className" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> <property name="driverProperties" > <props> <prop key="URL">jdbc:mysql://localhost:3306/Bookings</prop> <prop key="user">root</prop> <prop key="password">ACahlof</prop> </props> </property> <property name="uniqueName" value="jdbc/booking" /> <property name="minPoolSize" value="0" /> <property name="maxPoolSize" value="3" /> </bean> <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="bitronixTransactionManager"/> <property name="userTransaction" ref="bitronixTransactionManager"/> </bean> <bean id="bitronixTransactionManager" factory-method="getTransactionManager" class="bitronix.tm.TransactionManagerServices" depends-on="dataSource,dataSource1" destroy-method="shutdown"/>
In my testing code, I init the IoC container and get the JtaTransactionManager instance and start the transaction, in the transaction, will insert into database twice.
When execute txManager.commit(status), there is exception for second insert em.persist(bb), then only this persistence is rolled back, the former insert em.persist(ca) still commit to database.Code:ApplicationContext ctx = new FileSystemXmlApplicationContext("applicationContext.xml"); ((AbstractApplicationContext) ctx).registerShutdownHook(); JtaTransactionManager txManager = (JtaTransactionManager) ctx.getBean("txManager"); DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = null; BookingBasic bb = new BookingBasic(); bb.setBookingNo("booking-001"); bb.setCustomer("ABC"); CargoAspect ca = new CargoAspect(); ca.setId(1); ca.setCommodity("girls"); try { System.out.println("get the transaction status"); status = txManager.getTransaction(def); EntityManagerFactory emf = Persistence.createEntityManagerFactory("booking-jta"); EntityManager em = emf.createEntityManager(); System.out.println("Entity Manager is "+em); em.persist(ca); em.persist(bb); em.close(); System.out.println("commit the transaction"); txManager.commit(status); }catch(Exception e){ System.out.println("transaction commit exception"); e.printStackTrace(); try{ System.out.println("rollback the transaction"); txManager.rollback(status); }catch(Exception e1){ System.out.println("rollback exception"); e1.printStackTrace(); } }
Anyone know what is the problem with my code?
I want to rollback all the persistence including the former one. Do I have to do additional setting?
Your help will be greatly appreciated!


Reply With Quote
