java - MDP JMS Transaction rolls back then reprocesses message in an endless loop -
if enable transaction management on defaultmessagelistenercontainer specifying sessiontransacted=true
or transactionmanager=jmstransactionmanager
, whenever exception occurs in mdp, transaction rolled , message placed on queue. causes message processed again, transaction roll again on , on again creates endless loop.
i guess question ... missing here? why want message go on queue if means processed on , on again?
<!-- jms connection factory --> <bean name="jmsconnectionfactory" class="org.springframework.jndi.jndiobjectfactorybean"> <property name="jndiname" value="java:connectionfactory" /> </bean> <!-- jms transaction manager --> <bean id="jmstransactionmanager" class="org.springframework.jms.connection.jmstransactionmanager"> <property name="connectionfactory" ref="jmsconnectionfactory" /> </bean> <!-- destination inbound_email_q --> <bean name="inboundemaildestination" class="org.springframework.jndi.jndiobjectfactorybean"> <property name="jndiname" value="queue/inbound_email_queue" /> </bean> <!-- jmstemplate inbound_email_q --> <bean name="jmsinboundemailtemplate" class="org.springframework.jms.core.jmstemplate"> <property name="connectionfactory" ref="jmsconnectionfactory" /> <property name="defaultdestination" ref="inboundemaildestination" /> <property name="messageconverter" ref="xmlmessageconverter" /> </bean> <!-- jms asynchronous listener --> <bean id="emailmessageservicemdp" class="org.site.wso.core.jms.emailmessageservicemdp" /> <bean class="org.springframework.jms.listener.defaultmessagelistenercontainer"> <property name="connectionfactory" ref="jmsconnectionfactory"/> <!-- <property name="transactionmanager" ref="jmstransactionmanager" /> --> <!-- <property name="sessiontransacted" value="true"/> --> <property name="destination" ref="inboundemaildestination"/> <property name="messagelistener" ref="messagelistener"/> </bean> <!-- jms message listener adapter --> <bean id="messagelistener" class="org.springframework.jms.listener.adapter.messagelisteneradapter"> <constructor-arg> <bean class="org.site.wso.core.jms.emailmessageservicemdp"/> </constructor-arg> <property name="messageconverter" ref="xmlmessageconverter"/> </bean>
and here mdp:
public class emailmessageservicemdp implements messagedelegate { public void handlemessage(object object) { emailmessagerequestvo requestvo = (emailmessagerequestvo) object; try { //service call throw exception } catch (exception e) { throw new applicationexception(e); } } }
the message redelivery default behaviour [configured] jms implementation. it's endless debate relative usefulness of is, seem rather discard message potentially unrecoverable data, sort of retry sensible , conservative approach. example, in case, appear converting jms message email message , dispatching smtp server. if smtp gateway down, might want hold onto jms messages , reprocess them when gateway comes up.
in general options handling message failed processing (depending on jms implementation):
- ditch message.
- write message error queue.
- redeliver message after delay of n seconds.
- redeliver message n times , write message error queue.
- redeliver message after delay of n seconds x times , write message error queue.
if prefer #1, suppress exception, commit transaction , wave bye message. rest, jms configuration (or destination specific configuration) should handle those.
additionally, if want more specific, can interrogate message's getjmsredelivered() and/or implementation specific message header property indicates how many times message has been redelivered (supported jms implementations, not standard) , dispose of message accordingly.
Comments
Post a Comment