想象一个Java生态系统,其中三个独立的Spring Web应用程序在不同的JVM和不同的机器上运行(不涉及应用程序服务器,只需简单的servlet容器)。其中两个应用程序正在使用使用JPA访问的自己的数据库。现在第三个应用程序(协调器)向外界提供服务,一些服务功能执行远程操作,这需要以事务方式从其他两个应用程序中参与,这意味着如果其中一个应用程序无法在数据库,另一个也应该回滚。问题是:如何使用Spring实现这一目标?
目前我们正在使用REST在应用程序之间进行通信。显然,这不能支持交易,即使there are efforts to make this happen。
我发现JTA能够组织全球交易。 JTA涉及创建参与全局管理事务的XAResource实例。如果我理解正确,这些XAResource实例可以驻留在单独的JVM上。资源的初始化,提交和回滚通过JMS通信发生,这意味着它需要消息代理在参与者之间传输消息。存在各种JTA实现,我发现Atomikos似乎是最常用的。
现在,我不知道如果我在每个应用程序端都有一个Spring应用程序,这一切都会出现。我还没有找到任何通过网络进行JTA的示例项目。此外,我不承担代表XAResources的内容。如果我使用JPA,并说我在存储用户余额的应用程序中有一个Account对象,并且我必须减少协调器的余额,我应该创建一个允许减少余额的XAResource实现吗?或者XAResource是由JDBC驱动程序或Spring Data JPA等较低级别的东西实现的?在后一种情况下,我如何为事务协调器提供高级CRUD操作。
XAResource是一个较低级别的API。你可以为协调员编写自己的,但我认为这不是必要的。相反,在协调器上利用JMS + JTA,在应用服务器上利用JTA。
在正常情况下,你有这个:
请注意,JTA用于所有事务 - 这将是在所有服务器之间共享的全局TX。如果这些步骤中的任何一个失败,那么它们将被回滚。
一旦你完成所有设置,Spring应该能够使它透明。只需确保您的DAO和服务电话是交易性的。需要配置Atomikos,以便每个服务器使用相同的JTA tx管理器。
REST现在通过www.atomikos.com提供的Atomikos TCC实现支持交易 - 它是您所指的谈话中设计的实际实现......
HTH
这个答案是更详细的帖子的摘要:
How would you tune Distributed ( XA ) transaction for performance?
此图描绘了事务协调器和transatcion参与者之间的通信流。
在您的特定情况下,您的交易协调员将是Atomikos或Bitornix或任何其他提供商。流程中的所有内容(XID)对于开发人员来说是完全不可见的,并且仅由事务协调器执行。第一点开始,结束都在应用范围内。
现在根据你的问题。您不能在应用程序之间进行分布式事务。您可以在支持它们的基础架构之间进行分布式事务。如果您希望在由网络分隔的应用程序组件之间进行事务,则最好使用事务补偿,这是一个完全不同的主题。
您可以使用Distributed transaction执行的操作来自一个应用程序,一个服务,一个组件,无论是获取多个数据库还是支持XA的资源,然后执行某些事务。
我看到下面的帖子说明Atomikos有一些支持XA for REST的基础设施。通常,用于事务补偿的经典算法(例如Try Cancel Conirm attern)非常接近2阶段提交协议。在没有查看细节的情况下,我的猜测是他们实现了围绕这一行的实现。