2014-11-23 69 views
2

我正在使用WebSphere 8.5与EJB 3.1和JMS通用提供程序。与XA的JMS会话和JPA事务

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

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

我的问题:

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

在此先感谢,认为

回答

1

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

如果您的资源不是XA,那么您可以将bean设置为NOT_SUPPORTED并自行处理事务 - 意味着 - 管理2个单独的事务,首先是数据库,然后是管理JMS队列。但是,由于数据库事务将首先被提交,因此当发送消息失败时(因为无法回滚),您必须对其进行代码补偿,以避免数据库状态发生更改并且未发送消息的情况。

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

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

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