Tuesday, December 22, 2009

Rollback JMS transactions in MDB Vs MDP

If you are writing an application which has a message driven bean or a message driven POJO you might want to put back the message in JMS destination if there is an exception in your application logic. In other words rollback the JMS transaction if there is an exception in onMessage. On a side note the acknowledgement mode of the message is considered to be AUTO_ACKNOWLEDGE instead of CLIENT_ACKNOWLEDGE as in the AUTO mode the messages are automatically removed from the queue unless a rollback is issue. Let us discuss how to issue a rollback in the case of an MDB first and then in a MDP.

Issuing a rollback in a Message Driven Bean (MDB)

A sample MDB implements MessageDrivenBean and MessageListener as follows




public class ExampleMDB implements javax.ejb.MessageDrivenBean, javax.jms.MessageListener{

javax.ejb.MessageDrivenContext context;

public void setMessageDrivenContext(javax.ejb.MessageDrivenContext aContext) {
context = aContext;
}
// ejbCreate and ejbRemove methods go hear.

// onMessage needs to be implemented here
public void onMessage(javax.jms.Message inMessage) {

// do your business logic here
// if error in business logic rollback by calling
context.setRollbackOnly();


}

}



The message driven context is set by the container in a container managed bean. The rollback is achieved by calling the context.setRollbackOnly() when this happens the message is put back in the queue. One should be carefull as the onMessage will be called repeatedly until the processing is fine and the rollback is not issued.

Issuing a rollback in a Message Driven POJO (MDP)

In a Spring MDP the task of issuing a rollback is as straightforward as just throwing a RunTimeException.




public class ExampleMDP implements javax.jms.MessageListener{


public void onMessage(Message message) throws RuntimeException{

// if error in business logic throw a RuntimeException
}
}




When the MDP is configured in the application context xml file make sure it is sessionTransacted, by setting it's value to true. Refer to my earlier article
how-to-write-message-driven-pojo

No comments: