XA 事务中的数据一致性

2022-09-01 23:53:04

假设我们有一个数据库(例如Oracle)和一个JMS提供商(例如HornetQ)参与XA事务。一条消息被发送到 JMS 队列,并且一些数据将在同一分布式事务中持久保存在数据库中。提交事务后,消息使用者将读取持久化的数据,并在单独的事务中处理它们。

关于第一个XA事务,事务管理器可以执行以下事件序列(例如JBoss)

  1. 准备(大黄蜂Q)
  2. 准备(甲骨文)
  3. commit (HornetQ)
  4. commit (Oracle)

如果消息使用者在 HornetQ 中完成提交后开始读取数据,但仍在 Oracle 中执行,会发生什么情况?消息使用者是否会读取过时的数据?

这个问题可以推广到参与XA事务的任何类型的多个资源,即是否有可能在一个小的时间窗口(当执行提交阶段时)中,来自另一个并发事务的读取器可以获得不一致的状态(通过从一个资源读取提交的数据并从另一个资源读取过时的数据)?

我想说的是,事务资源防止这种情况的唯一方法是在准备阶段完成后阻止受影响数据的所有读取器,直到发出提交。这样,上面提到的示例消息使用者将阻塞,直到数据提交到数据库中。


答案 1

遗憾的是,XA 事务不支持一致性。当映射到 CAP 定理时,XA 可解决跨多个数据存储的可用性和分区容错性。在这样做时,它必须牺牲一致性。使用XA时,您必须接受最终一致性。

在任何情况下,创建 CP 或 AP 系统都非常困难,无论您的数据存储还是事务模型如何,您都将面临此问题。


答案 2

我对基于Weblogic JMS和Oracle 11g的不同环境有一些经验。在这个答案中,我认为它的工作原理完全相同。我希望我的答案能帮助你。

在我们的例子中,有一个“遥远”系统,它必须根据本地系统内发生的不同事件进行通知。另一个系统也进入我们的数据库,因此用例似乎与您的问题几乎相同。事件的顺序与你完全一样。在测试系统上,没有一个faulire。每个人都认为它会起作用,但我们中的一些人怀疑它是否是正确的解决方案。随着软件投入生产,一些 BPM 进程的运行是不可预测的。因此,对你的问题有一个简单的答案:是的,这是可能的,每个人都应该意识到这一点。

我们的解决方案(在我看来)不是一个精心策划的解决方案,但是我们认识到两个提交之间的小时间窗口正在制动系统,因此我们在队列中添加了一些“延迟”(如果我记得的话,就像1-2分钟)。完成另一个提交并读取一致的数据就足够了。在我看来,这不是最好的解决方案。它没有解决同步问题(如果预言机事务的长度超过1-2分钟怎么办?

这是一篇值得一读的精彩博客文章,最后一个解决方案对我来说似乎是最好的。我们在其他系统中实现了它,它的工作方式更好。请务必注意,您应该限制重试次数(重读)以防止线程“卡住”。(带有一些错误报告。由于这种限制,到目前为止我无法找到更好的解决方案,所以如果有人有更好的选择,我期待着听到它。:)

编辑:错别字。


推荐