由于需要分布式交易,我正在进入JTA世界,而且我不确定javax.jms.ConnectionFactory
和javax.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);
中使用此会话,并且使用UserTransaction
或MessageProducer
两个Commit
执行完美无瑕。
我不明白的是,我是如何使用Rollback
方法而得到javax.jms.XAConnectionFactory.createConnection()
来完成工作的?什么是Session
角色?
我还要补充一点,我查看了这两个类的源代码(以及javax.jms.XAConnectionFactory
),并且我验证了XA类没有覆盖javax.jms.BasicConnectionFactory
。
答案 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事务,因此该调用将失败。