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

时间:2010-11-07 12:08:42

标签: java jms jndi jta atomikos

由于需要分布式交易,我正在进入JTA世界,而且我不确定javax.jms.ConnectionFactoryjavax.jms.XAConnectionFactory之间的差异,或者更准确地说它是如何{{1}执行我期望只有javax.jms.ConnectionFactory可以为我做的事情。

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

我正在运行一个带有虚拟应用程序的小型POC,我将JMS提供程序(javax.jms.XAConnectionFactory)注册为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); 中使用此会话,并且使用UserTransactionMessageProducer两个Commit执行完美无瑕。

我不明白的是,我是如何使用Rollback方法而得到javax.jms.XAConnectionFactory.createConnection()来完成工作的?什么是Session角色?

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

2 个答案:

答案 0 :(得分:2)

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管道,看起来像是< em>常规JMS会话。

答案 1 :(得分:1)

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

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

另一方面,如果您正在进行1PC,您将看不到两种类型的连接工厂之间的任何差异。它会完全展示您描述的行为。

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