javax.jms.ConnectionFactory 和 javax.jms.XAConnectionFactory 之间的差异

发布于 2024-09-30 15:51:04 字数 1500 浏览 0 评论 0原文

由于需要分布式事务,我正在进入 JTA 的世界,并且我不确定 javax.jms.ConnectionFactoryjavax.jms.XAConnectionFactory 之间的差异或者更准确地说,javax.jms.ConnectionFactory 怎么可能执行我期望只有 javax.jms.XAConnectionFactory 能为我做的事情。

详细信息:我使用 Atomikos Essentials 作为我的事务管理器,我的应用程序在 Apache Tomcat 6 上运行。

我正在运行一个带有虚拟应用程序的小型 POC,其中有我的 JMS 提供程序 (OpenMQ)注册为 JNDI 资源。

<Resource name="jms/myConnectionFactory" auth="Container"  
 type="com.atomikos.jms.AtomikosConnectionFactoryBean"  
 factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"   
uniqueResourceName="jms/myConnectionFactory"  
xaConnectionFactoryClassName="com.sun.messaging.XAConnectionFactory"  
maxPoolSize="3"/>

奇怪的问题是,在我的代码中,我这样做了:

Context ctx = new InitialContext();  
ConnectionFactory queueConnectionFactory =  
(ConnectionFactory)ctx.lookup("java:comp/env/jms/myQueueFactory");  
javax.jms.Connection connection = queueConnectionFactory.createConnection();  
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);

稍后在代码中,我在 UserTransaction 中使用此会话,并且它与两个带有 MessageProducerMessageProducer 一起完美地执行代码>提交或回滚

我不明白的是,我如何使用 javax.jms.XAConnectionFactory.createConnection() 方法并获得执行该工作的 Session ? javax.jms.XAConnectionFactory 的作用是什么?

我还要补充一点,我已经查看了这两个类(以及 javax.jms.BasicConnectionFactory)的源代码,并且验证了 XA 类不会覆盖 createConnection 。

I'm entering the world of JTA, due to need of distributed transactions, and I'm uncertain about the differences between javax.jms.ConnectionFactory and javax.jms.XAConnectionFactory or more accurately how can it be that javax.jms.ConnectionFactory performed what I expected only javax.jms.XAConnectionFactory can do for me.

The details: I'm using Atomikos essentials as my transaction manager and my app is running on Apache Tomcat 6.

I'm running a small POC with a dummy app where I have my JMS provider (OpenMQ) registered as a JNDI resource.

<Resource name="jms/myConnectionFactory" auth="Container"  
 type="com.atomikos.jms.AtomikosConnectionFactoryBean"  
 factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"   
uniqueResourceName="jms/myConnectionFactory"  
xaConnectionFactoryClassName="com.sun.messaging.XAConnectionFactory"  
maxPoolSize="3"/>

And the strange issue is that in my code I do this:

Context ctx = new InitialContext();  
ConnectionFactory queueConnectionFactory =  
(ConnectionFactory)ctx.lookup("java:comp/env/jms/myQueueFactory");  
javax.jms.Connection connection = queueConnectionFactory.createConnection();  
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);

And later in the code I use this session in a UserTransaction and it performs flawlessly with two MessageProducers with either Commit or Rollback.

What I don't understand is how can it be that I'm using javax.jms.XAConnectionFactory.createConnection() method and I get a Session which does the job? What's javax.jms.XAConnectionFactory role?

I'll also add that I've looked at the source code of both classes (and javax.jms.BasicConnectionFactory) and I verified that the XA class does not override createConnection.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沉鱼一梦 2024-10-07 15:51:04

ConnectionFactory 和 XAConnectionFactory 之间的核心区别在于 XAConnectionFactory 创建 XAConnections,而 XAConnections 创建 XASession。 XASessions 代表了真正的区别,因为(引用 JMS JavaDocs:)

XASession 接口通过添加对 JMS 提供者对 Java Transaction API (JTA)(可选)的支持的访问来扩展 Session 的功能。这种支持采用 javax.transaction.xa.XAResource 对象的形式。

换句话说,XASession 为 XA 实例提供了事务感知。然而,这个特定的实现是可选的,即使对于完全兼容的 JMS 提供者也是如此。来自同一个 JavaDoc:

XAResource 提供了一些相当复杂的工具,用于交错处理多个事务、恢复正在进行的事务列表等。 JTA 感知的 JMS 提供者必须完全实现此功能。这可以通过使用支持 XA 的数据库服务来完成,或者 JMS 提供者可以选择从头开始实现此功能。
应用程序服务器的客户端被给予它认为是常规的 JMS 会话。在幕后,应用程序服务器控制底层 XASession 的事务管理。

换句话说,提供程序可能要求您指定 XA 或非 XA JMS 资源,或者,就像您的情况一样,提供者可以通过看似常规的 JMS 会话透明地执行所有 JTA 管道。

The core of the difference between ConnectionFactory and XAConnectionFactory is that the XAConnectionFactory creates XAConnections which create XASessions. XASessions represent the real difference because (to quote from the JMS JavaDocs:)

The XASession interface extends the capability of Session by adding access to a JMS provider's support for the Java Transaction API (JTA) (optional). This support takes the form of a javax.transaction.xa.XAResource object.

In other words, the XASession is what gives the XA instances their transactional awareness. However, this specific implementation is optional, even for a fully compliant JMS provider. From the same JavaDoc:

An XAResource provides some fairly sophisticated facilities for interleaving work on multiple transactions, recovering a list of transactions in progress, and so on. A JTA aware JMS provider must fully implement this functionality. This could be done by using the services of a database that supports XA, or a JMS provider may choose to implement this functionality from scratch.
A client of the application server is given what it thinks is a regular JMS Session. Behind the scenes, the application server controls the transaction management of the underlying XASession.

In other words, the provider may require that you specify an XA or non-XA JMS resource, or, as would seem to be in your case, the provider may perform all the JTA plumbing transparently with what appears to be a regular JMS Session.

我的影子我的梦 2024-10-07 15:51:04

实际上,您提供的示例代码都不会使用 XA 功能。如果所需的只是您的消息位于同步点下,那么您可以使用一阶段提交 (1PC)。但是,例如,如果您希望 JMS 消息和数据库更新发生在单个协调工作单元中,那么您将使用两阶段提交 (2PC),即 XA。协调同一传输提供者上的两个消息生产者不需要 XA 2PC。

如果您使用 2PC,那么除了 COMMIT 和 ROLLBACK 之外,您还会在代码中的某处调用 BEGIN。你的例子中缺少这个动词就是为什么我说你看起来没有做 2PC。 BEGIN 调用将与事务管理器进行通信,以在参与的资源管理器之间建立事务上下文。然后 COMMIT 将导致消息和数据库更新在一个工作单元中完成。这里有趣的是,如果您只有一个参与的资源管理器,某些传输会默默地优化您回到 1PC。在这种情况下,看起来好像您正在使用 2PC,但实际上得到的是 1PC。由于只有一个资源管理器,因此这种优化不会损失可靠性。

另一方面,如果您使用 1PC,您将看不到两种类型的连接工厂之间有任何差异。它将准确地表现出您所描述的行为。

最后要考虑的情况是您使用 ConnectionFactory 并尝试调用 BEGIN。由于非 XA 连接工厂无法参与协调的 XA 事务,因此此调用应该失败。

Actually, none of the example code you provided would exercise XA functionality. If all that is required is that your messages are under syncpoint, then you can get by with 1-phase commit (1PC). However if you want, for example, that JMS messages and DB updates occur in a single coordinated unit of work then you would use 2-phase commit (2PC) which is XA. Coordinating across two message producers on the same transport provider does not require XA 2PC.

If you were using 2PC, then in addition to COMMIT and ROLLBACK you would be calling BEGIN somewhere in the code. The lack of that verb in your example is why I said it looks like you are not doing 2PC. The BEGIN call would communicate with the transaction manager to establish a transaction context across the participating resource managers. Then the COMMIT would cause the messages and the DB updates to finalize in one unit of work. The interesting thing here is that if you have only one participating resource manager, some transports will silently optimize you back down to 1PC. In that case it looks as though you are doing 2PC but are really getting 1PC. Since there is only one resource manager there is no loss of reliability in this optimization.

On the other hand, if you are doing 1PC you won't see any difference between the two types of connection factory. It would exhibit exactly the behavior you describe.

The last case to consider is that you use ConnectionFactory and try to call BEGIN. Since the non-XA connection factory cannot participate in a coordinated XA transaction, this call should fail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文