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.

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.