背景
我有Spring Client应用程序,它使用RMI为两台服务器提供服务。在客户端中,我将实体保存到数据库(简单),并使用实体的详细信息对两个服务器进行rmi调用。我在服务器上使用Spring 3.0.2,客户端是一个简单的Spring-mvc站点。
要求
我的要求是,如果任何rmi调用对整个事务回滚的服务器失败,那么实体就不会保存在客户端上,如果rmi调用成功,那么它也会回滚。
我对分布式事务比较陌生,但我想我想要一个使用RMI调用的XA事务。
我确实在主题here上找到了一个很好的链接,但它没有提到调用两个远程方法调用到不同服务器时的模式。我希望在推荐阅读方面听到更多有关该主题的内容,以及有关如何使用spring实现此目的的任何指示。是否正在使用事务管理器?
谢谢。
答案 0 :(得分:3)
以下是理论上如何处理这种情况。首先,您需要在每个节点上安装多个JTA分布式事务管理器。一个充当主人,另一个充当奴隶。主服务器协调分布式事务的提交/回滚到从服务器。存在独立的JTA实现,例如, JOTM
Vanilla RMI不支持传播上下文信息,例如操作的事务ID。但我认为RMI有一些钩子可以扩展到支持它。您可以查看Carol。
您需要使用XAResource来包装事务中的参与者,以便他们可以在分布式事务中登记。主服务器需要向从服务器发送提交/回滚消息,这需要使用XATerminator进行相应的操作。
JTA规范只是一个分布式事务 manager ,事务日志中的操作记录需要由服务器完成。存在用于事务日志管理的库,例如, HOWL
我不认为Spring可以使用 - 即使使用分布式事务管理器 - 也可以轻松实现。我曾经尝试过使用RMI和分布式事务控制来自独立客户端和几个从属服务器。这是关于它的blog post。这很复杂。
如果您使用带有IIOP的Java EE应用程序服务器,则可以免费获得所有这些功能。 IIOP支持分布式事务传播。客户端可以是application client container,您可以使用UserTransaction控制交易。这实际上是一种罕见的情况,我认为使用应用服务器是非常合理的。
但是说,分布式事务是复杂的事情,可能导致启发式故障,如果一个节点死亡则超时,以及复杂的恢复过程。
我的最后建议是:尽可能找到一个不涉及分布式交易的设计。这会让你变得更轻松。
您可以在BPEL compensation mechanism中汲取灵感。可能存在用于错误处理和鲁棒性的其他设计方法,其可以避免使用分布式事务。
答案 1 :(得分:1)
据我所知,Spring本身并不管理分布式事务。它可以使用JtaTransactionManager
,它依次委托给Java EE服务器的事务协调器。因此,据我所知,这种交易仅适用于在应用程序容器中注册的数据源。
您可以尝试编写自己的XAResource
实现(不确定它是否是最好的方法,但仍然是)并将其注册到应用程序容器中,但Spring对此不会有太多帮助。