Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javax.jms.ConnectionFactory和javax.jms.XAConnectionFactory之间的差异_Java_Jms_Jndi_Jta_Atomikos - Fatal编程技术网

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

javax.jms.ConnectionFactory和javax.jms.XAConnectionFactory之间的差异,java,jms,jndi,jta,atomikos,Java,Jms,Jndi,Jta,Atomikos,由于分布式事务的需要,我正在进入JTA的世界,我不确定javax.jms.ConnectionFactory和javax.jms.XAConnectionFactory之间的区别,或者更准确地说,javax.jms.ConnectionFactory如何实现我所期望的,只有javax.jms.XAConnectionFactory才能为我做到 细节:我使用Atomikos essentials作为事务管理器,我的应用程序运行在ApacheTomcat6上 我正在运行一个带有虚拟应用程序的小型PO

由于分布式事务的需要,我正在进入JTA的世界,我不确定
javax.jms.ConnectionFactory
javax.jms.XAConnectionFactory
之间的区别,或者更准确地说,
javax.jms.ConnectionFactory
如何实现我所期望的,只有
javax.jms.XAConnectionFactory
才能为我做到

细节:我使用Atomikos essentials作为事务管理器,我的应用程序运行在ApacheTomcat6上

我正在运行一个带有虚拟应用程序的小型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"/>
在后面的代码中,我在一个
UserTransaction
中使用了这个会话,它使用两个
MessageProducer
s
Commit
Rollback
完美地执行

我不明白的是,我怎么会使用
javax.jms.XAConnectionFactory.createConnection()
方法,然后得到一个
会话来完成任务?什么是
javax.jms.XAConnectionFactory
角色


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

ConnectionFactory和XAConnectionFactory之间的区别的核心是XAConnectionFactory创建XAConnections,后者创建XASessions。XASessions代表了真正的差异,因为(引用:)

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

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

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


换句话说,提供程序可能要求您指定XA或非XA JMS资源,或者,在您的情况下,提供程序可能会使用常规JMS会话透明地执行所有JTA管道

实际上,您提供的示例代码中没有一个能够实现XA功能。如果所需的只是消息在同步点下,那么您可以通过1阶段提交(1PC)来完成。但是,例如,如果您希望JMS消息和DB更新发生在单个协调的工作单元中,那么您可以使用两阶段提交(2PC),即XA。在同一传输提供程序上跨两个消息生成器进行协调不需要XA 2PC

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

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


最后一个需要考虑的是使用连接工厂并尝试调用开始。由于非XA连接工厂无法参与协调的XA事务,因此此调用将失败。

谢谢。关于OpenMQ(我的提供商)是如何运作的,您有什么具体的信息吗?此外,我认为我将切换到“XA”,使其成为独立于提供商的,而不依赖于偶然发生的事情。我不熟悉OpenMQ。但你的测试似乎表明一切正常。如果您使用数据库或另一个JMS实例执行两阶段提交事务,我会更谨慎一点,但事实上,这并不太复杂。我确实在
UserTransaction
中使用了会话,这是开始JTA事务的不同说法。我确实需要2PC,因为我担心JMS、DB和事务缓存。啊,好的。听起来2PC被优化到了1PC,因为所描述的测试使用了两个消息生成器,而不是两个不同的资源管理器。
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);