3

We have what we believe is a fairly common XA use case:

  1. read a message from an in-queue
  2. write some data to a database
  3. write a response message to an out-queue (which is different from the in-queue)

However we also need a way to handle internal errors and poison messages. The control flow we have in mind is something like this:

  1. read the message from the in-queue
  2. write to the database
    • if there's an exception roll back the database transaction
    • if there's no exception run commit phase1 on the database
  3. if everything went fine (no rollback and commit phase1 ok) write a success message to the out-queue
  4. if either commit phase1 on the database failed or there was an exception and the database transaction was rolled back write a failure message to the out-queue
  5. commit the in-queue, the out-queue and the database (unless rolled by because of an exception)

Is this a good approach, should we do it differently? How can we do this with EJBs?

We're using EJB 3.1 on JBoss AS 7.2 / EAP 6.1, coding against Narayana directly is an option. The JDBC driver is ojdbc7-12.1.0.1 and the JMS RAR is MQ Series (don't know the version).

Philippe Marschall
  • 4,452
  • 1
  • 34
  • 52
  • That will radically change the XA protocol, don't you think? And I'm pretty sure you won't be able to do that. Why don't you simply configure your JMS provider to let the message listener attempt to consume the message N times, and send the message to an error queue if all the N attempts have failed? – JB Nizet Oct 06 '13 at 14:14
  • I look at as sort of a nested transaction. Yes, I know JTA doesn't support nested transactions but this is an edge case where the resource itself doesn't have to support nested transactions, only the transaction manager (Narayana AFAIK does). – Philippe Marschall Oct 06 '13 at 17:35
  • Um, how would you have commit to the database in both step 2 and step 5? what would be there for step 5 to commit? Couldn't you just use standard distributed transaction so that everything is committed at step 5, and if any of them fails, the whole process is rolled back and you send a failure message to out queue? – eis Oct 16 '13 at 08:17

1 Answers1

3

What you could do is to use the Java EE event mechanism to get a notification when your transaction fails and create a subsequent output message.

See

You need to use a new transaction to write to the out queue to avoid rolling back the message writing as well.

You will still have the message in the input queue which caused the exception, since the rollback will prevent the successfull consumption. You need to handle that separately, for example by the JMS provider.

Thomas
  • 11,272
  • 2
  • 24
  • 40