涉及RMI调用的Spring分布式事务可能吗?

背景

我有Spring Client应用程序,它使用RMI为两台服务器提供服务。 在客户端中,我将实体保存到数据库(简单),并使用实体的详细信息对两个服务器进行rmi调用。 我在服务器上使用Spring 3.0.2,客户端是一个简单的Spring-mvc站点。

要求

我的要求是,如果任何rmi调用对整个事务回滚的服务器失败,那么实体不会保存在客户端上,如果rmi调用成功,那么它也会回滚。

我对分布式事务比较陌生,但我想我想要一个使用RMI调用的XA事务。

我确实找到了关于这个主题的一个很好的链接,但它没有提到调用两个远程方法调用到不同服务器时的模式。 我希望在推荐阅读方面听到更多有关该主题的内容,以及有关如何使用spring实现此目的的任何指示。 是否可以使用事务管理器?

谢谢。

以下是理论上如何处理这种情况。 首先,您需要在每个节点上拥有多个JTA分布式事务管理器。 一个充当主人,另一个充当奴隶。 主服务器协调分布式事务的提交/回滚到从服务器。 存在独立的JTA实现,例如JOTM 。

Vanilla RMI不支持传播上下文信息,例如操作的事务ID。 但我认为RMI已经挂钩,因此可以扩展它以支持它。 你可以看看卡罗尔 。

您将需要使用XAResource来包装事务中的参与者,以便它们可以在分布式事务中登记。 主服务器需要向从服务器发送提交/回滚消息,这需要使用XATerminator进行相应的操作。

JTA规范只是一个分布式事务管理器 ,事务日志中的操作记录需要由服务器完成。 存在用于事务日志管理的库,例如HOWL 。

我不认为Spring可以使用 – 即使使用分布式事务管理器 – 也可以轻松地使用它。 我尝试过一次使用RMI与分布式事务控制从一个独立的客户端和几个从属。 这是一篇关于它的博客文章 。 这很复杂。

如果您使用带有IIOP的Java EE应用程序服务器,您可以免费获得所有这些。 IIOP支持分布式事务传播。 客户端可以是应用程序客户端容器 ,您可以使用UserTransaction控制事务。 这实际上是极少数情况之一,我认为使用应用程序服务器是非常合理的。

但是,分布式事务是复杂的事情,可能导致启发式故障,如果一个节点死亡则超时,以及复杂的恢复过程。

我的最后建议是:尽可能找到一个不涉及分布式交易的设计。 这会让你变得更轻松。

您可以从BPEL 补偿机制中汲取灵感。 可能存在用于error handling和鲁棒性的其他设计方法,其可以避免使用分布式事务。

据我所知,Spring本身并不管理分布式事务。 它可以使用JtaTransactionManager ,它又委托给Java EE服务器的事务协调器。 所以据我所知,这种交易仅适用于在应用程序容器中注册的数据源。

您可以尝试编写自己的XAResource实现(不确定它是否是最好的方法,但仍然是)并将其注册到应用程序容器中,但Spring对此不会有太多帮助。