0
votes

Scenario:

in method onMessage of my MDB I basically do:

  • print a label
  • update database saying: "label was printed"

what happens is that (for some reason) I have a Internal Database Exception, as a consequence seems to me that transactions is rolled back, message is redelivered and I have an infinite loop in which label is printed (infinite print).

What I want is NOT redeliver the message.

Before posting this issue I read these articles:

I'm using Glassfish 2.1, ActiveMQ, EclipseLink, method onMessage contains try/catch clause in which I log the Exception

snippet code:

@MessageDriven(mappedName = JMSConstants.COMMAND_SPOOL_TOPIC_JNDI, activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
    @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
    @ActivationConfigProperty(propertyName = "clientId", propertyValue = "PrinterCommandSpoolMessageBean"),
    @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "PrinterCommandSpoolMessageBean"),
    @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = JMSSelector.PRINT_COMMAND_SELECTOR)
})
public class PrinterCommandSpoolMessageBean implements MessageListener {

    private final static Logger LOGGER = Logger.getLogger(PrinterCommandSpoolMessageBean.class.getName());
    
    @EJB
    private CoreServiceRemote coreService;

    @Override
    public void onMessage(Message message) {
       
        LOGGER.info("*********************  message arrived ********************");
        if (message instanceof MapMessage) {

            CommandSpool cs = null;
            try {
                MapMessage mapMessage = (MapMessage) message;

                //missing code

                if (actualCopies >= copies) {
                    coreService.updateCommandSpool(cs.getId(), CommandSpoolStatus.EXECUTED);            
                    coreService.setSensorIssued(ps.getSensorUUID());    
                } else {
                    coreService.updateCommandSpool(cs.getId(), CommandSpoolStatus.NOT_EXECUTED);
                }

            } catch (Exception ex) {
                LOGGER.log(Level.WARNING, "Exception", ex);
                if (cs != null) {
                    coreService.resetCommandSpool(cs.getId());
                }
            
        }
    }
}
1
Message redelivery is linked to transaction rollback. Is the thrown exception the one being caught in your catch block? Do you throw it again after logging ?ramp
i added a snippet, i don't throw Exception againpikimota
Method wich fails is setSensorIssued()pikimota

1 Answers

1
votes

Are you sure that the coreService.resetCommandSpool(cs.getId()) is not throwing another exception ?

Given that you catch all exceptions, do you want your MDB to be transactional? You could always start a new transaction on your ejb methods.