我有一个架构问题,关于如何在Java/Java EE中处理事务性和可伸缩性的大任务.
一般的挑战
我有一个Web应用程序(Tomcat现在,但不应该限制解决方案空间,所以只需要用它来说明我想要实现的目标).这个Web应用程序分布在几个(虚拟和物理)节点上,连接到中央DBMS(在这种情况下是MySQL,但同样,这不应该限制解决方案......)并且能够处理大约1000个用户,服务页面,正如你对平均基于网络的信息系统所期望的那样.
现在,有一些任务影响了大部分数据,系统应该进行优化,以便合理地快速执行这些任务.(比顺序处理所有内容更快,即).所以我将任务并行并将其分布在几个(或所有)节点上:
(注意:处理的数据部分是独立的,因此这里没有数据库或锁定冲突).
问题是,我希望(整个)任务是事务性的.因此,如果其中一个并行子任务失败,我希望将所有其他任务作为结果回滚.否则,从域的角度来看,系统将处于可能不一致的状态.
目前的实施
正如我所说,当前的实现使用Tomcat和MySQL.节点使用JMS进行通信(因此有一个JMS服务器,调度程序为每个子任务发送消息;执行程序从消息队列中获取任务,执行它们,并将结果发布到调度程序收集的结果队列中.调度程序阻塞并等待所有结果进入,如果一切正常,它将以OK状态终止.
这里的问题是所有执行程序都有自己的本地事务上下文,因此图片看起来像这样:
如果由于某种原因,其中一个子任务失败,则回滚本地事务并且调度程序获得错误结果.(这里有一些故障保护机制,它试图重复失败的事务,但我们假设由于某种原因,一个任务无法完成).问题是系统现在处于一个状态,其中除了一个之外的所有事务都已提交并完成.而且因为我不能让最后一笔交易成功完成,所以我无法摆脱这种状态.
可能的解决方案
这些是我到目前为止所遵循的想法:
我自己可以以某种方式实现特定于域的回滚机制.因为分发器知道已经执行了哪些任务,所以它可以显式地恢复效果(例如,在某处存储旧值并将已提交的值恢复回先前的值).当然,在这种情况下,我必须保证其他进程之间不会发生任何变化,所以只要大型操作正在运行,我还必须将系统设置为只读状态.或多或少,我需要模拟业务逻辑中的事务...
我可以选择不在一个大事务中并行化并在单个节点上执行所有操作(但正如开头所述,我需要加快处理速度,因此这不是一个选项......)
我试图了解一般的XATransactions或分布式事务,但这似乎是一个高级的Java EE功能,它没有在所有Java EE服务器中实现,并且不能真正解决这个基本问题,因为似乎没有是一种在异步调用中将事务上下文传递到远程节点的方法.(例如,EJB规范3.1的 4.5.3部分:"客户端事务上下文不会通过异步方法调用进行传播.从Bean Developer的视图来看,永远不会有来自客户端的事务上下文.")
问题
我忽略了什么吗?是不是可以在多个节点上异步分发任务,同时具有可以作为整体回滚的(共享)事务状态?
感谢任何指示,提示,命题......