如何设计全局分布式事务(无数据库)?JTA可以用于无数据库事务吗?

zx_*_*ing 16 java jta distributed-transactions

我认为这是一个相当普遍的问题:如何将我的业务逻辑放在分布式系统环境中的全局事务中?举个例子,我有一个包含几个子任务的TaskA:

TaskA {subtask1,subtask2,subtask3 ...}

这些子任务中的每一个都可以在本地机器或远程机器上执行,我希望TaskA通过事务以原子方式(成功或失败)执行.每个子任务都有一个回滚函数,一旦TaskA认为操作失败(因为其中一个子任务失败),它就会调用子任务的每个回滚函数.否则,TaskA会提交整个事务.

为此,我按照"审计试用"事务模式来记录每个子任务,因此TaskA可以知道子任务的操作结果,然后决定回滚或提交.这听起来很简单,但是,困难的部分是如何将每个子任务与全局事务相关联?

当TaskA开始时,它启动一个关于哪个子任务什么都不知道的全局事务.为了使子任务意识到它,我必须将事务上下文传递给每个子任务调用.这真是太可怕了!我的子任务可以在新线程中执行,也可以通过AMQP代理发送消息在远程执行,很难巩固上下文传播的方式.

我做了一些研究,如"交易模式 - 四个交易相关模式的集合","异步消息传递环境中的已检查事务",这些都没有解决我的问题.他们要么没有实际的例子,要么没有解决上下文传播问题.

我想知道人们如何解决这个问题 因为这种交易必须在企业软件中很常见.

X/Open XA只是解决方案吗?JTA可以在这里提供帮助(我没有考虑JTA,因为它与数据库事务有关,我使用Spring,我不想在我的软件中涉及另一个Java EE应用服务器).

有些专家可以和我分享一些想法吗?谢谢.

结论

Arjan和Martin给出了非常好的答案,谢谢.最后我没有这样做.经过更多的研究,我选择了另一种模式" CheckPoint " 1.

根据我的要求,我发现我的"审核试验事务模式"的意图是知道操作已进行到哪个级别,如果失败,我可以在重新加载某些上下文后在失败的地点重新启动它.实际上这不是事务,它在失败后没有回滚其他成功的步骤.这是CheckPoint模式的精髓.然而,研究分布式交易的东西让我学到了很多有趣的东西.除了Arjan和Martin提到的.我还建议人们深入研究这个领域,看看CORBA,这是一个众所周知的分布式系统协议.

Yve*_*tin 11

您是对的,由于JTA API提供的XA事务管理器,您需要两阶段提交支持.

据我所知,Spring本身并没有提供事务管理器实现.该JtaTransactionManager中唯一的代表,以通常的JavaEE实现提供现有的实现.

因此,您必须将JTA实现插入Spring才能完成有效的工作.以下是一些建议:

然后,您必须实现资源管理器以支持两阶段提交.在JavaEE世界中,它包含一个打包为RAR存档的资源适配器.根据资源类型,以下方面是读取/实现:

作为示例,我建议您查看经典的"带文件的事务"问题的实现:


Arj*_*jms 7

如果要编写自己的事务资源,确实需要实现XAResource并让它加入正在进行的事务,处理来自事务管理器的准备和提交请求等.

数据源是最知名的事务资源,但如上所述,它们不是唯一的.您已经提到了JMS提供程序.各种缓存解决方案(例如Infinispan)也是事务性资源.

实现XAResources并使用JTA API的低级部分和更低级别的JTS(Java事务服务)对于胆小者来说不是一项任务.API可能过时,整个过程几乎没有记录.

原因是创建自己的事务资源的常规企业应用程序极为罕见.事务性的整个要点是为外部观察者做一个原子的动作.

在绝大多数情况下可观察到意味着该动作的效果存在于数据库中.几乎每个数据源都是事务性的,因此完全覆盖了用例.

另一个可观察到的影响是消息是否已发送,现有消息传递解决方案也完全覆盖了该消息.

最后,更新内存映射中的(群集范围)是另一个可观察到的效果,主要缓存提供程序也涵盖了这种效果.

在使用外部企业信息系统(EIS)进行操作时,对事务影响的需求仍然存在,并且根据经验,此类系统的供应商提供事务感知连接器.

剩下的用例颤抖是如此之小,以至于显然没有人真的费心去写太多.有一些博客涉及一些基础知识,但很多将留给你自己的实验.

如果您真的绝对需要走这条路,并且如果现有的交易资源之一无法满足您的需求,请尝试自行验证.