Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

AutoAcknowledge Mode in MDB

 
Joe Harry
Ranch Hand
Posts: 10128
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Guys,

Why do we ever need this when we know that the Container is going to ignore it depending on the transaction within which this MDB is called.
 
Jim Janssens
Ranch Hand
Posts: 210
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
An MDB does not have to run inside a container transaction.

When an MDB is running inside a container transaction, the ack mode is indeed ignored since the acknowldgement of the message will depend on the success of the container transaction.

When an MDB does NOT run inside a container transaction, (tx attribute is NOT_SUPPORTED for example) the reception of messages happens in a local transaction. You can influence the acknowledgement by supplying an extra parameter.

For example; if you specify AUTO_ACK, the container will acknowledge every message if the onMessage() executes successfully. If you supply DUPS_OK the container will acknowledge them in batch. This means that if you already processed message 5 till 10, and the application crashes before the acknowledgement has been done, those messages will be re-delivered. So, you gain performance (less acknowledgements) but your application must be prepared to handle duplicates.

According to me, the difference between a local transaction with AUTO_ACK and a container transaction (REQUIRED for example) is that if you call another resource from the MDB it will not participate in that transaction (there is no 2PC).

So if you have:

onMessage()
{
//1.do some processing
//2.save some data to database
//3.do some processing
}


If at step 3 a runtime exception would be thrown, the message receipt will be rolledback as expected. However, step 2 (the database interaction) would already be commited, by either using a local transaction itself or starting a JTA transaction. Either way, it did not participate in the local transaction started by the message receipt, so its work is already done and commited and will not be rolledback if exceptions occur later in the MDB local transaction. If you expect that the database interaction also rolls back, you should probably use a container/jta transaction (thus specifying REQUIRED)

EDIT:

I have checked the (core ejb3) spec on this. The spec does indeed mention (13.3.5) that you should not specify the ACK mode as the session is transactional and managed by the container. I think this is what you are refering too.

However, its my guess that this is for sending and/or receiving messages not within an MDB.
Its also my guess that this is only true if there is currently a JTA transaction going on (either CMT or BMT).
If there is no transaction, then these arguments will not be ignored.
If you specifiy transacted = true (the second parameter is then ignored), you can control the commit/rollback by calling commit()/rollback() on the JMS session.
If you specified false, the second parameter will tell the session how the acknowledgement should be controlled (either automatically, or either client by calling acknowledge() on the message)

Note that the later is only the case when NOT in a JTA transaction. When creating a session in a bean running in a JTA transaction the ack mode parameter will be ignored.

Now, for the second part (MDB) my explanation above is not entirely correct.

If you look at the spec 5.4.14 (or 6.3 : http://www.huihoo.org/jfox/jfoxmq/jms_tutorial/jmsj2ee.html) then this is the whole story;

When using an MDB the ACK_MODE is never ignored. That is, the ACK_MODE you configure your MDB with (not dealing with JMS API objects directly for receiving in an MDB)

When using ACK_MODE 'AUTO' in combination with CMT, the messages are acknowledgement by the container when the transaction is successfull.
If the transaction is rolledback, the message is redelivered.
When the transaction attribute is not_supported, the outcome is unclear. However, its my guess that the BMT semantics apply in that case (no runtimeexception = message acknowledged, redelivery otherwise)


When using ACK_MODE 'AUTO' in combination with BMT, the MDB has no control over the transaction in which the message is received. When the bean starts a new transaction (using the UserTransaction) and rolls its back, it will have no influence on redelivery of the message (the reception of the message happens in a separate transaction in the BMT case). The only way a message is redeliverd is by throwing a RuntimeException from the onMessage method.

When you use 'DUPS_OK' instead of 'AUTO' the same semantics apply, with the difference that the container will acknowledge messages in batch and thus duplicates can occur.
[ December 18, 2008: Message edited by: Jim Janssens ]
 
Joe Harry
Ranch Hand
Posts: 10128
3
Eclipse IDE Mac PPC Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That was a wonderful explanation. Thanks!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic