Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Message-driven bean (EJB3) in WebSphere 7, XA transactions, Error handling

I am a relative newb to EJB. Background: I have an MDB using the WebSphere default messaging provider receiving MapMessages that has a java.sql.DataSource to do some work, using preparedstatement, jdbc transaction, etc. I set up the MDB in the ibm-ejb-bnd.xml and ejb-jar.xml using a JCA adapter with an activation-spec and destination name. I added a java.sql.DataSource in the ejb-jar and ibm-ejb-jar-bind. I also added the DataSource in the MessageListener with an @Resource annotation.

2 scenarios I am having trouble understanding (first scenario fixed, see update)...

Container Managed MDB: The DataSource driver is not XA compatible so I enabled "Last Participant Support" in WebSphere. Still, when the MDB transaction-type is set to Container, I get an error upon commit:

[11/28/11 10:56:10:988 MST] 0000002e RegisteredRes E   WTRN0063E: An illegal attempt to commit a one phase capable resource with existing two phase capable resources has occurred.

Maybe this is because after the DataSource commits, returns to MessageListener which commits making it the last participant? I believe the default messaging provider in WAS 7 is XA compatible although I haven't seen any documentation that says so explicitly.

The message reruns 4 more times immediately after the first error (even though there should be a 30 second delay according to the ActivationSpec in WebSphere). Each time the same error is thrown. According to the MessageListener it finished without error, so this error is part of the wonderful invisible container managed transaction. I don't think I need XA global transactions since there is only one DataSource aside from JMS, I handled transaction rollback programmatically. Also the JMS msg, MDB is asynchronous, AUTO-ACKNOWLEDGE. Once the message has been received, it can be acknowledged.

If I introduce an application error so there is an Exception, I see this error 5 times immediately (no delay):

[11/28/11 10:16:18:857 MST] 0000002b LocalExceptio E   CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "onMessage" on bean...

So I switched to................

Bean Managed MDB: Commit is working without the XA error and only happens once. However error handling is still not behaving as I expect or want! In the MessageListener class, caught Exceptions throw a EJB Exception, which I think should cause the MDB to have my desired behavior: The cause of the exception does not matter to me, when an MDB throws a caught Exception, shouldn't the MDB be retried according to the properties in the WebSphereActivationSpec? Instead the message goes to the MessageListener 5 times immediately throwing the same error as Container Managed MDB: "EJB threw an unexpected (non-declared) exception..."

If I throw a RuntimeException, the "unexpeded (non-declared) expecetion" message doesn't happen, but the message is still retried 4 times immediately, instead of waiting for the retry delay.

Thanks for reading, any help or insight is greatly appreciated!

UPDATE: I ended up solving the XA compatibility issues by switching the datasource to XA compatible. In WAS admin console: Resources->JDBC Providers->DB2 Universal JDBC Driver Provider->Change implementation class name to: com.ibm.db2.jcc.DB2XADataSource

I'm still having the same problem when the message fails though. It is retried immediately instead of according to the ActivationSpec in WAS.

like image 750
Morgan Dowell Avatar asked Nov 28 '11 17:11

Morgan Dowell


1 Answers

I believe that the retry interval in Activation spec is regarding closed connections, not failed messages.

You should define the interval you want in the SIB Destination

Buses > BUS > Destinations > DESTINATION

Look at Exception destination

Maximum failed deliveries per message is how many times the message will be sent until it declared failed (default is 5 which is why you get another 4 times)

When the messages fails it will either move to a exception destination queue, or if set to None will retry after a certain amount of time which is set at the bus level but can be overridden for each destination (see Override messaging engine blocked retry timeout default)

like image 182
Aviram Segal Avatar answered Nov 13 '22 02:11

Aviram Segal