Forum Stats

  • 3,854,538 Users
  • 2,264,379 Discussions
  • 7,905,721 Comments

Discussions

MDB with CMT rollback and redelivery despite getRollbackOnly being false.

tizzo
tizzo Member Posts: 1
edited May 31, 2012 6:15AM in Java Message Service (JMS)
I've got a message-driven bean using container managed transactions. Message processing involves some operations that can throw EJB exceptions, but those exceptions are caught and handled internally.

For some of these exceptions, my transaction commits and all is well, which is what I expect. But for other exceptions, the transaction is rolled back and the message redelivered, which is causing me problems. Worse, my efforts to code around these problems involve using getRollbackOnly() before returning from onMessage() to try to detect an impending rollback and prepare accordingly - however getRollbackOnly() invariably returns false - even if the transaction ends up rolling back an the message gets redelivered.

While it's not completely clear, the Javadoc for [url http://docs.oracle.com/javaee/6/api/javax/ejb/EJBContext.html#getRollbackOnly()]getRollbackOnly() strongly implies that it should return true whether rollbackOnly was requested by the application, or set automatically by an exception.

So my first question is - should it be possible for the container to roll back the transaction without telling me it's going to do so through getRollbackOnly(), or is this a bug? And if it's not a bug, is there some other way for me to know whether my transaction will commit or not?

I'm using Glassfish 3.1 with the built-in JMS provider. JSE6 on RHEL5.
@Resource
private MessageDrivenContext mdbContext;

public void onMessage(final Message inMessage) {
    try {
        // Sometimes throws, exception caught, transaction commits, no problem.
        doSomethingThatThrows();

        // Sometimes throws, exception caught and handled, but transaction rolled back and msg redelivered.
        doSomethingElseThatThrows();
    } catch (JMSException ex) {
        logExceptionMessage(ex);
    } finally {
        boolean rollback = mdbContext.getRollbackOnly();
        logRollbackValue(rollback);  // ALWAYS false.
    }
}
Edited by: 937599 on May 30, 2012 11:11 AM
Tagged:

Answers

  • r035198x
    r035198x Member Posts: 2,499
    >
    So my first question is - should it be possible for the container to roll back the transaction without telling me it's going to do so through getRollbackOnly(), or is this a bug? And if it's not a bug, is there some other way for me to know whether my transaction will commit or not?
    getRollbackOnly is the right way to check.
    You only catch a JMSException? If you don't want any roll backs due to exceptions then you must catch all possible exceptions.
    Also, it could be that an exception is happening in the logRollbackValue method itself.
  • This is a good question, which isn't specific to JMS but applies to how transaction rollback is handled in EJBs generally.

    Can I suggest you ask in the GlassFish forum, since that's where many EJB experts congregate?
    http://www.java.net/forums/glassfish/glassfish

    Nigel
This discussion has been closed.