hibernate - Spring + tomee JTA transactions -


i have been struggling through trying build simple application deploys tomee using spring, hibernate , jms. believe of configurations correct (have mysql xa data source , xa active mq connection factory) things aren't working expect. have simple service writes using injected entity manager pushes jms within 1 method annotated being transactional (spring annotation) message listener being delivered these messages before transaction committed in spring.

i've tried using jms template , xa connection factory directly, neither works properly. template configured jta transaction manager received jndi. ideas @ hints why jms sends not participating in same transaction database writes?

spring configuration:

<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans"     xmlns:tx="http://www.springframework.org/schema/tx"     xmlns:context="http://www.springframework.org/schema/context"     xmlns:aop="http://www.springframework.org/schema/aop"     xmlns:jee="http://www.springframework.org/schema/jee"     xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"     xmlns:task="http://www.springframework.org/schema/task"     xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"     xmlns:util="http://www.springframework.org/schema/util"     xmlns:encryption="http://www.jasypt.org/schema/encryption"     xmlns:jms="http://www.springframework.org/schema/jms"     xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd                                             http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd                                             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd                                             http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd                                             http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd                                             http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd                                             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd                                             http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd                                             http://www.jasypt.org/schema/encryption http://www.jasypt.org/schema/encryption/jasypt-spring31-encryption-1.xsd                                             http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.1.xsd"     default-autowire="bytype" default-lazy-init="false">      <context:component-scan annotation-config="false" base-package="org.superbiz" />      <bean class="org.springframework.orm.jpa.defaultjpadialect" />     <bean class="org.springframework.dao.annotation.persistenceexceptiontranslationpostprocessor" />      <bean class="org.springframework.beans.factory.annotation.requiredannotationbeanpostprocessor" />     <bean class="org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor" />     <bean class="org.springframework.context.annotation.commonannotationbeanpostprocessor">             <property name="alwaysusejndilookup" value="false" />             <property name="jndifactory" >                     <ref local="jndifactory"/>             </property>     </bean>      <bean id="jndifactory" class="org.springframework.jndi.support.simplejndibeanfactory">             <property name="resourceref" value="true" />     </bean>      <bean id="printtemplate" class="org.springframework.jms.core.jmstemplate">             <property name="connectionfactory">                     <ref local="jmsfactory" />             </property>             <property name="defaultdestinationname" value="resources/jms/printqueue" />             <property name="deliverypersistent" value="true"/>             <!-- <property name="sessiontransacted" value="true"/> -->             <!-- <property name="sessionacknowledgemode" value="0"/> -->     </bean>      <bean id="persisttemplate" class="org.springframework.jms.core.jmstemplate">             <property name="connectionfactory">                     <ref local="jmsfactory" />             </property>             <property name="defaultdestinationname" value="resources/jms/persistqueue" />             <property name="deliverypersistent" value="true"/>             <!-- <property name="sessiontransacted" value="true"/> -->             <!-- <property name="sessionacknowledgemode" value="0"/> -->     </bean>      <bean class="org.springframework.orm.jpa.support.persistenceannotationbeanpostprocessor">             <property name="defaultpersistenceunitname" value="movie-unit" />             <property name="persistencecontexts">                     <map>                             <entry key="movie-unit" value="persistence/movie-unit" />                     </map>             </property>     </bean>      <context:component-scan base-package="org.superbiz.ejb" annotation-config="false">             <context:exclude-filter type="annotation" expression="org.springframework.stereotype.controller"/>     </context:component-scan>      <jee:jndi-lookup id="jmsfactory" jndi-name="resources/jms/connectionfactory" expected-type="javax.jms.connectionfactory" />      <tx:jta-transaction-manager />      <tx:annotation-driven transaction-manager="transactionmanager"/>      <bean id="printbean" class="org.superbiz.mdb.printbean"/>     <bean id="persistbean" class="org.superbiz.mdb.persistbean"/>      <jms:listener-container container-type="default" connection-factory="jmsfactory" cache="none" transaction-manager="transactionmanager" concurrency="1" receive-timeout="1000" prefetch="-1">             <jms:listener destination="resources/jms/printqueue" ref="printbean" />             <jms:listener destination="resources/jms/persistqueue" ref="persistbean" />     </jms:listener-container>  </beans> 

tomee.xml (cobbled http://tomee-openejb.979440.n4.nabble.com/mdb-doesn-t-read-messages-td4666169.html)

<resource id="activemqresourceadapter" type="activemqresourceadapter">     brokerxmlconfig=broker:(vm://localhost) </resource>  <resource id="resources/jms/connectionfactory" type="javax.jms.connectionfactory">     resourceadapter = activemqresourceadapter </resource>  <resource id="resources/jms/xaconnectionfactory" class-name="org.apache.activemq.activemqxaconnectionfactory">     brokerurl = vm://localhost     resourceadapter = activemqresourceadapter </resource>  <resource id="resources/jms/printqueue" type="javax.jms.queue"/> <resource id="resources/jms/persistqueue" type="javax.jms.queue"/>  <resource id="mysql database" type="datasource">     jdbcdriver  com.mysql.jdbc.jdbc2.optional.mysqlxadatasource     jdbcurl jdbc:mysql://localhost/test     username    test </resource> 

i've tried several ways include not using xaconnectionfactory jmstemplate configured sessiontransacted , not, removing jmstemplate , creating connection/session/producer/message connectionfactory, i've run issue each time. manually creating connection/session/producer/message connectionfactory notice 20 items attempt write database send jms queue start being read before services transaction completes.

as far can tell configured correctly (although wrong since pulled lots of places). goal able use jmstemplate instead of manually creating connection/session/etc myself, i'm @ loss why happening @ point ideas appreciated.

i've bumped logging of spring jtatransactionmanager , see following happening when @transactional method called

debug org.springframework.transaction.jta.jtatransactionmanager - creating new transaction name [org.superbiz.ejb.movies.send]: propagation_required,isolation_default; '' debug org.springframework.transaction.jta.jtatransactionmanager - initiating transaction commit 

then see mdb code trying retrieve item entitymanager (which works/fails intermittently). when succeeds see this

printing mdb: director: director0title: title0year: 0 debug org.springframework.transaction.jta.jtatransactionmanager - initiating transaction commit debug org.springframework.transaction.jta.jtatransactionmanager - creating new transaction name [org.springframework.jms.listener.defaultmessagelistenercontainer#0]: propagation_required,isolation_default 

when fails see this

/***************** broken ***************/ /*******************435265*****************/ /***************** broken ***************/ debug org.springframework.transaction.jta.jtatransactionmanager - initiating transaction commit debug org.springframework.transaction.jta.jtatransactionmanager - creating new transaction name [org.springframework.jms.listener.defaultmessagelistenercontainer#0]: propagation_required,isolation_default 

i've further cranked logging

[org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] debug org.springframework.transaction.jta.jtatransactionmanager - creating new transaction name [org.springframework.jms.listener.defaultmessagelistenercontainer#1]: propagation_required,isolation_default  **bold** [org.springframework.jms.listener.defaultmessagelistenercontainer#0-1] debug org.springframework.transaction.jta.jtatransactionmanager - creating new transaction name [org.springframework.jms.listener.defaultmessagelistenercontainer#0]: propagation_required,isolation_default  [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] trace org.springframework.transaction.support.transactionsynchronizationmanager - initializing transaction synchronization  [org.springframework.jms.listener.defaultmessagelistenercontainer#0-1] trace org.springframework.transaction.support.transactionsynchronizationmanager - initializing transaction synchronization  [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] trace org.springframework.transaction.support.transactionsynchronizationmanager - bound value [org.springframework.jms.connection.jmsresourceholder@81032a4] key [org.apache.activemq.ra.activemqconnectionfactory@5ee0c65d] thread [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1]  [org.springframework.jms.listener.defaultmessagelistenercontainer#0-1] trace org.springframework.transaction.support.transactionsynchronizationmanager - bound value [org.springframework.jms.connection.jmsresourceholder@eaebd86] key [org.apache.activemq.ra.activemqconnectionfactory@5ee0c65d] thread [org.springframework.jms.listener.defaultmessagelistenercontainer#0-1]  [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] debug org.springframework.transaction.jta.jtatransactionmanager - participating in existing transaction [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] trace org.springframework.transaction.interceptor.transactioninterceptor - getting transaction [org.superbiz.mdb.persistbean.onmessage] [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] trace org.springframework.transaction.support.transactionsynchronizationmanager - retrieved value [org.springframework.jms.connection.jmsresourceholder@81032a4] key [org.apache.activemq.ra.activemqconnectionfactory@5ee0c65d] bound thread [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] persisted finished, not yet committed leaving persist, should commit [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] trace org.springframework.transaction.interceptor.transactioninterceptor - completing transaction [org.superbiz.mdb.persistbean.onmessage] [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] trace org.springframework.transaction.jta.jtatransactionmanager - triggering beforecommit synchronization [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] trace org.springframework.transaction.jta.jtatransactionmanager - triggering beforecompletion synchronization [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] trace org.springframework.transaction.support.transactionsynchronizationmanager - removed value [org.springframework.jms.connection.jmsresourceholder@81032a4] key [org.apache.activemq.ra.activemqconnectionfactory@5ee0c65d] thread [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] **bold** [org.springframework.jms.listener.defaultmessagelistenercontainer#1-1] debug org.springframework.transaction.jta.jtatransactionmanager - initiating transaction commit  entering print /***************** broken ***************/ /*******************597852*****************/ /***************** broken ***************/ 

in case defaultmessagelistenercontainer#1-1 persist bean , 0-1 bean retrieves entity id , prints content.

i not 100% sure how read this, it's interesting me dmlc#1-1 commits after new transaction has begun on dmlc#0-1, dmlc#0-1 sees message. have thought dmlc#0-1 have needed start new transaction see or since received jms message entity should persisted database.

contents of persist bean @override @transactional public void onmessage(message message) { textmessage msg = (textmessage)message; int x;

    try {         x = integer.parseint(msg.gettext());         movie movie = new movie("director" + x, "title" + x, x);         entitymanager.persist(movie);         final long id = movie.getid();         template.send(new messagecreator() {             @override             public message createmessage(session session) throws jmsexception {                 return session.createtextmessage(long.tostring(id));             }         });         system.out.println("persisted finished, not yet committed");         system.out.println("leaving persist, should commit");     } catch (exception e) {         e.printstacktrace();     }  } 

contents of print bean

public void onmessage(message message) {     system.out.println("entering print");     final textmessage textmessage = (textmessage) message;      try {         long id = long.parselong(textmessage.gettext());         movie movie = entitymanager.find(movie.class, id);         if(movie == null){             system.out.println("/***************** broken ***************/");             system.out.println("/*******************" + id + "*****************/");             system.out.println("/***************** broken ***************/");          } else {             system.out.println("updating: "+ movie);         }     } catch (exception e) {         e.printstacktrace();     }  } 

the entire app available @ https://github.com/jej2003/simple-spring, running vanilla tomee 1.7.1 necessary hibernate jars added tomee/lib directory.

i'm @ loss here, no 1 run jta transactions in tomee spring?

after ton of debugging turns out failure not in jta implementation, more understanding of jta in general. while jta ensures both transactions commit, not enforce order apparently of transactions. answer provided here https://jira.spring.io/browse/spr-12535, stéphane nicoll.


Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -