Database 跨SpringWeb应用程序的分布式事务

Database 跨SpringWeb应用程序的分布式事务,database,spring,transactions,jta,distributed-transactions,Database,Spring,Transactions,Jta,Distributed Transactions,想象一个Java生态系统,其中三个独立的SpringWeb应用程序运行在不同的JVM和不同的机器上(不涉及应用程序服务器,只涉及简单的servlet容器)。其中两个应用程序使用自己的数据库,该数据库使用JPA访问。现在,第三个应用程序(协调器)向外部世界提供服务,一些服务功能执行远程操作,需要其他两个应用程序以事务方式参与,这意味着如果其中一个应用程序无法在数据库中进行数据操作,另一个也应该回滚。问题是:如何使用Spring实现这一点 目前,我们正在使用REST在应用程序之间进行通信。显然,这无

想象一个Java生态系统,其中三个独立的SpringWeb应用程序运行在不同的JVM和不同的机器上(不涉及应用程序服务器,只涉及简单的servlet容器)。其中两个应用程序使用自己的数据库,该数据库使用JPA访问。现在,第三个应用程序(协调器)向外部世界提供服务,一些服务功能执行远程操作,需要其他两个应用程序以事务方式参与,这意味着如果其中一个应用程序无法在数据库中进行数据操作,另一个也应该回滚。问题是:如何使用Spring实现这一点

目前,我们正在使用REST在应用程序之间进行通信。显然,这无法支持事务,即使

我发现JTA能够组织全球事务。JTA涉及创建参与全局管理事务的XAResource实例。如果我理解正确,这些XAResource实例可以驻留在单独的JVM上。资源的初始化、提交和回滚通过JMS通信进行,这意味着它需要一个消息代理在参与者之间传输消息。存在各种JTA实现,我发现Atomikos似乎是最常用的


现在我不明白的是,如果我在每个应用程序端都有一个Spring应用程序,这一切是怎么发生的。我还没有发现任何通过网络进行JTA的示例项目。我也不明白XA资源代表什么。如果我使用JPA,并且假设我在应用程序中有一个Account对象存储用户余额,并且我必须从协调器中减少余额,那么我是否应该创建一个允许减少余额的XAResource实现?或者XAResource是由较低级别的东西实现的,比如JDBC驱动程序或Spring数据JPA?在后一种情况下,如何为事务协调器提供高级CRUD操作。

XAResource是一个较低级别的API。你可以为协调员写你自己的,但我认为没有必要。相反,在协调器上利用JMS+JTA,在应用服务器上利用JTA

在正常情况下,您会有以下情况:

  • 协调器接收请求并启动JTA事务
  • 协调器通过JMS调用应用程序1
    • 应用程序1接收JMS消息
    • 应用程序1使用JTA调用DB 1
  • 协调器通过JMS调用应用程序2
    • 应用程序2接收JVM消息
    • 应用程序2使用JTA调用DB 2
  • 协调人提交tx
  • 请注意,JTA用于所有事务-这将是一个在所有服务器上共享的全局TX。如果这些步骤中的任何一个失败,那么它们将被回滚


    Spring应该能够在完成所有设置后使其透明。只需确保DAO和服务调用是事务性的。需要对Atomikos进行配置,以便每个服务器使用相同的JTA tx管理器。

    REST现在通过www.Atomikos.com上提供的Atomikos TCC实现支持事务-这是您所指谈话中设计的实际实现


    HTH

    这个答案是对更详细帖子的总结:

    此图描述了事务协调器和事务参与者之间的通信流。

    在您的特殊情况下,您的事务协调员将是Atomikos或Bitornix或任何其他提供商。对于开发人员来说,流程中位于末尾(XID)以下的所有内容都是完全可见的,并且仅由事务协调器执行。第一点开始、结束在应用范围内

    现在根据你的问题。应用程序之间不能有分布式事务。您可以在支持它们的基础结构之间进行分布式事务处理。如果您想让应用程序组件之间的事务由网络分隔,那么最好使用事务补偿,这是一个完全不同的主题

    对于分布式事务,您可以从一个应用程序、一个服务、一个组件(无论什么)获取支持XA的多个数据库或资源,然后执行一些事务


    我看到下面的帖子说Atomikos拥有某种支持XA for REST的基础设施。一般来说,事务补偿的经典算法(如Try-Cancel-Conirm模式)非常接近于两阶段提交协议。没有深入了解细节,我猜他们在这方面做了些什么。

    谢谢,这是有道理的。你知道有什么样的应用程序吗?另外,我应该如何从协调器应用程序调用其他应用程序?我是否必须使用JMS来正确传播事务上下文,或者我可以使用其他东西(比如SpringHTTP调用器)?很抱歉,我现在明白了,我必须通过JMS调用其他应用程序。不过,一个例子会让事情变得更清楚。有没有可用的示例代码?我只找到了以下文档:我不知道哪个Atomikos版本包含TCC实现。请不要发布其他堆栈交换问题的链接答案。取而代之的是,在这里包括答案的基本部分,并针对这个特定问题定制答案。@Mogsdad好的,我会这样做的。