使用XA进行JMS会话和JPA事务

时间:2014-11-23 01:26:49

标签: ejb jms jta websphere-8 xa

我正在将WebSphere 8.5与EJB 3.1和JMS Generic提供程序结合使用。

我需要使用无状态会话bean作为生产者在队列中编写消息。 EJB使用TransactionAttributeType.REQUIRED进行注释,因为我需要执行一些" DB insert"在我在队列上发送消息并使用这些消息读取生产者写的记录之前。

问题是如果我定义了一个JDBC非XA数据源,那么生产者会将消息写入队列,但服务器会抱怨本地资源的2阶段提交失败(我认为是数据源本身)并且没有调用MDB的onMessage方法。如果我定义JDBC XA一切正常。

我的问题:

  • JMS会话是否必须是默认的XA资源?为什么?
  • 如果我将JMS连接工厂配置为在JTA事务中创建非XA JMS会话,会发生什么?这是一种不好的做法吗?
  • 如果消费者在生产者仍在数据库上完成操作时开始消费消息,会发生什么?消费者是否会看到数据库上的更改,因为它们位于同一个事务中?

提前致谢,问候

1 个答案:

答案 0 :(得分:1)

JMS会话是否必须是默认的XA资源?为什么?
您需要两个资源才能成为XA。这是分布式事务 - 在2个不同的资源中 - 数据库和JMS队列。要参与同一个交易,他们都必须是XA(可以选择在交易中使用一个非XA资源 - 使用最后一个参与者支持,但我不建议这样做。)

如果您的资源不是XA,那么您可以将bean设置为NOT_SUPPORTED并自己处理事务 - 意味着 - 管理2个单独的事务,首先是数据库,第二个是JMS队列。但是,由于db事务将首先被提交,所以当发送消息失败时(因为你不能回滚),你必须编码补偿它,以避免数据库状态发生变化并且你没有发送消息的情况。 / p>

如果我将JMS连接工厂配置为在JTA事务中创建非XA JMS会话会怎样?
如果另一个资源是该事务的一部分(例如数据库),那么您将获得关于2阶段提交支持的例外。

如果消费者在生产者仍在数据库上完成操作时开始消费消息会发生什么?
我不清楚你在问什么。如果生产者首先写入数据库,然后在一个XA事务中写入队列,它们将同时提交,因此消费者将无法首先看到该消息。
但是,如果您创建2个单独的事务(一个用于数据库访问,第二个用于队列访问),则可能会出现这种情况,如果您首先提交队列,则该消费者可以读取该消息。但在这种情况下,如果没有提交,消费者将无法看到对数据库的更改。

消费者是否会看到数据库中的更改,因为它们位于同一个交易中?
生产者和消费者不在同一个事务中(生产者创建消息和提交,消费者开始单独的事务来阅读)。