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

我正在进入JTA的世界,由于需要分布式交易,我不确定
javax.jms.ConnectionFactory
javax.jms.XAConnectionFactory
之间的差异,或者更准确地说,how0ѭ是如何执行我所期望的只有
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
中使用了这个会话,并且它使用
Commit
Rollback
两个ѭ9完美无瑕地执行。 我不明白的是,我是如何使用
javax.jms.XAConnectionFactory.createConnection()
方法而得到一个
Session
来做这项工作的?什么是
javax.jms.XAConnectionFactory
角色? 我还要补充一点,我已经查看了两个类的源代码(和
javax.jms.BasicConnectionFactory
),并且我验证了XA类没有覆盖
createConnection
。     
已邀请:
ConnectionFactory和XAConnectionFactory之间的区别在于XAConnectionFactory创建了创建XASessions的XAConnections。 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资源,或者,在您的情况下,提供程序可能会透明地执行所有JTA管道,看起来像是常规JMS会话。     
实际上,您提供的示例代码都不会执行XA功能。如果所需要的只是您的消息在同步点下,那么您可以通过单阶段提交(1PC)。但是,如果您希望,例如,JMS消息和数据库更新发生在单个协调的工作单元中,那么您将使用XA的两阶段提交(2PC)。协调同一传输提供商上的两个消息生成器不需要XA 2PC。 如果您使用的是2PC,那么除了COMMIT和ROLLBACK,您将在代码中的某处调用BEGIN。在你的例子中缺少那个动词就是为什么我说它看起来你没有做2PC。 BEGIN调用将与事务管理器通信,以在参与的资源管理器之间建立事务上下文。然后COMMIT将导致消息和数据库更新在一个工作单元中完成。这里有趣的是,如果你只有一个参与资源管理器,一些传输将默默地优化你回到1PC。在这种情况下,它看起来好像你正在做2PC但真的得到1PC。由于只有一个资源管理器,因此优化中不会丢失可靠性。 另一方面,如果您正在进行1PC,您将看不到两种类型的连接工厂之间的任何差异。它会完全展示您描述的行为。 最后一个需要考虑的情况是你使用ConnectionFactory并尝试调用BEGIN。由于非XA连接工厂无法参与协调的XA事务,因此此调用将失败。     

要回复问题请先登录注册