3

I'm using WebSphere 8.5 with EJB 3.1 and JMS Generic provider.

I need to write messages in a queue using a stateless session bean as a producer. The EJB is annotated with the TransactionAttributeType.REQUIRED because I need to perform some "DB insert" before I send messages on a queue and consume these messages reading records wrote by the producer.

The problem is if I define a JDBC non XA datasource, the producer writes the messages in queue but the server complains about a failed 2 phase-commit of a local resource (the Datasource itself I think) and doesn't call the onMessage method of the MDB. If I define a JDBC XA everything works.

My questions:

  • Is JMS session required to be a default XA resources? And why?
  • What happen if I configure my JMS connection factory to create a non XA JMS session in a JTA Transaction? Is that a bad practice?
  • What happen if the consumer starts to consume message while the producer is still finishing his operations on database? Would the consumer see changes on database because they are in the same transaction?

Thanks in advance, regards

Gas
  • 17,601
  • 4
  • 46
  • 93
Yanosh
  • 368
  • 5
  • 15

1 Answers1

3

Is JMS session required to be a default XA resources? And why?
You need both resources to be XA. This is distributed transaction - among 2 different resources - database and JMS queue. To participate in one, same transaction they both must be XA (there is an option to have one non XA resource in transaction - using last participant support, but I wouldn't recommend that) .

If your resources are not XA, then you may set bean to NOT_SUPPORTED and handle transaction by yourself - means - manage 2 separate transactions, first to database and second to JMS queue. However, since db transaction will be commited first, you would have to code compensating it, when sending message fails (as you cannot do rollback), to avoid situation were database state has changed and you didn't send the message.

What happens if I configure my JMS connection factory to create a non XA JMS session in a JTA Transaction?
If another resource is a part of that transaction (e.g. database) you will have exception about 2 phase-commit support.

What happen if the consumer starts to consume message while the producer is still finishing his operations on database?
It's not clear for me, what you are asking. If producer first writes to the database, then writes to the queue in one XA transaction, they will be commited at the same time, so consumer will not be able to see the message first.
However, if you create 2 separate transactions (one for db access, second for queue access) you could have a situation, if you first commit the queue, that consumer could read the message. But in that case, consumer will not be able to see changes to the db, if they are not commited.

Would the consumer see changes on database because they are in the same transaction?
Producer and consumer are not in the same transaction (producer creates message and commits, consumer starts separate transaction to read).

Gas
  • 17,601
  • 4
  • 46
  • 93
  • Hi, I know its very long since the question is answered. But I m having an issue similar to the one mentioned above. Within a transaction, we are trying to persist data in DB and send JMS message to the consumer from producer. But the problem is consumer receives the message before even the data is committed. Both persistence and messaging in producer use XA-datascource and XA connection factory. Any pointer to resolve this race condition? More info on - https://stackoverflow.com/questions/54343688/cdi-event-observer-handling-on-server-crash-and-restart – Gandhi Jan 29 '19 at 04:42
  • @Gandhi I saw your question is related to JBoss. JBoss has lots of issues with XA transactions. By default even if you think you configured datasource for xa it may use plain transactions. If both - database driver and jms provider - fully support XA, it should work correctly - meaning only after successful commit DB and JMS message should be available in the queue. (unless I didnt correctly understand your question there.) – Gas Jan 29 '19 at 16:46
  • Hi, I m using DefaultJMSConnectionFactory pooled connection factory whose transaction type is XA and OracleXADataSource. Have also confirmed xa datasource is active via management console. But still it fails. Any thoughts Gas? – Gandhi Jan 30 '19 at 05:17
  • @Gandhi ,what JMS provider are you using? (embedded JBoss, or third party?) If you are using embedded jboss probably your connection factory is incorrect. Check this post - http://www.mastertheboss.com/jboss-server/jboss-jms/sending-jms-messages-over-xa-with-wildfly-jboss-as - it looks like you have to use `@Resource(mappedName="java:/JmsXA")` to have XA in JMS. As I've already wrote JBoss is very unreliable in case of XA, maybe try [OpenLiberty](https://openliberty.io/) or [WebSphere Liberty](http://wasdev.net) – Gas Jan 30 '19 at 16:52
  • Thanks again for response Gas. I m using the same what you have specified - "java:/JmsXA" which in turn refers to "" in standalone-ha.xml – Gandhi Jan 31 '19 at 04:30