7

背景

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

要求

我的要求是,如果任何一个 rmi 调用对整个事务回滚的服务器都失败,那就是实体没有保存在客户端上,如果任何一个 rmi 调用成功,这也将回滚。

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

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

谢谢你。

4

2 回答 2

3

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

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

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

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

我不认为可以使用 Spring——即使使用分布式事务管理器——来轻松地做到这一点。我曾经尝试将 RMI 与由独立客户端和多个从属设备控制的分布式事务一起使用。这是一篇关于它的博客文章。这相当复杂。

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

但话虽如此,分布式事务是复杂的事情,它可能导致启发式失败、一个节点死亡时超时以及复杂的恢复过程。

我最后的建议是:如果可能,尝试找到不涉及分布式事务的设计。这将使您的喜欢更容易。

您或许可以从 BPEL补偿机制中汲取灵感。可能还有其他用于错误处理和健壮性的设计方法可以避免使用分布式事务。

于 2010-06-30T11:41:21.843 回答
1

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

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

于 2010-06-30T10:40:35.547 回答