EJB design: Rolling back database but not message in MDB?

  1. Rolling back database but not message in MDB? (2 messages)

    We're working on an MDB system that handles job requests. The typical scenario is that a job request gets sent in a JMS message, the worker MDB receives the message and updates the database (in a bounded-size transaction), and then the worker MDB sends a status message.

    Setting the worker MDB's transaction type to Container and transaction attribute to Required is almost perfect for the situation where everything goes well (the request message receipt, database update, and "OK" status message will all be part of a single transaction). It also works well for cases where unexpected contention causes a transient failure in the database commit; if the database commit fails (due to database contention), the request message receipt will get rolled back, and another worker MDB will get to try it again.

    But where this does NOT work well is if the worker MDB detects some problem with the work request which is inherent in the work request itself. In this case, there is no way that *any* worker MDB could *ever* complete the request. Assuming that the worker MDB does some database work before discovering the error, the behavior we want is for the worker MDB to be able to roll back its database update, but NOT roll back its message receipt. It wants to commit the message receipt, roll back the database update, and then commit sending an error status message.

    Is there any kind of sane way to do this in EJB 2.0 containers? Do we need to go to bean-managed transactions for this particular bean type? How would you even handle separately committing database updates vs. message traffic in a bean-managed MDB? Are there any references or pointers to info about this?

    Thanks very much for all suggestions,
  2. Hi Rob,
            If I understood your request correctly, you might want to delegate the task of performing the database update to another session bean, and set the session beans transaction attribute to RequiresNew. This would isolate the DB transaction from the message receipt. So if there is any error on the database side, the session bean would rollback the changes but it would have no impact on the MDB. The MDB can catch the exception from the session and do whatever it needs to do afterwards. Hope this helps

  3. Hm, that is interesting. So message beans can use other session beans? Now that I think of it, why wouldn't they be able to? It's an interesting idea. Thanks! :-)