java - 如何正确使用JTA资源回收方法?

标签 java jta

我试图了解如何正确调用 javax.transaction.xa.XAResource.recovery(int) 方法。我正在处理一个手动调用 XA 操作的环境,并且没有容器资源管理器。

JavaDocs 只是说可能存在 TMSTARTRSCANTMENDRSCANTMNOFLAGS 标志值,但没有提供发生情况的解释当使用任何这些标志或其组合时。

我梳理了 Glassfish 代码,了解它们可能对标志值执行的操作,但没有发现任何有用的信息。我研究过 Artemis - 仅当使用单独的 TMSTARTRSCAN 标志时,它才会返回所有未完成的事务。 Postgres JDBC 几乎是一样的,除了 TMSTARTRSCAN 可以与 TMENDRSCAN 结合使用,所有内容也可以在一次调用中返回。

我认为这些标志存在的原因是为结果提供某种分页,以防有太多未完成的事务。因此,处理这个问题的正确方法是:

  • 使用 TMSTARTRSCAN 调用 recover()
  • 使用 TMNOFLAGS 调用 recover(),直到结果数组为空
  • 使用TMENDRSCAN调用recover()

对于上述所有调用,请准备好处理返回的 XID 值。

但我希望有人指出或解释其如何运作。

更新

当 @kayaman 优雅地向我指出 X/Open 的 XA 规范时,我可以看到我的假设可能是正确的。该标准更清楚地解释了预期的行为,但由于数组大小预期的差异,它并没有一对一地应用于 Java 实现。该标准解释了何时不调用 recover(TMENDRSCAN),但对于 Java 来说并不清楚,也不清楚错误地调用它是否会导致异常。

最佳答案

这个 JTA 函数特别不直观,因为 XA 规范中的底层 C API 的许多设计细节在转换为 Java 时被破坏了,基于不完全正确的假设,它们在处理内存管理的语言中并不重要自动。

首先,澄清您是否从事务管理器(实际调用恢复方法的组件)或资源管理器(实现该方法的组件)的角度进行操作非常重要。 Glassfish 是 TM,Artemis 和 Postgres 是 RM。

TM以迭代方式调用recover,从TMSTARTRSCAN开始(打开一个新的迭代器,获取第一批结果),可选地跟随TMNOFLAGS(检查进一步的结果批处理,直到一个返回为空,表明已到达末尾)并以 TMENDRSCAN 终止(关闭迭代器,允许 RM 释放其持有的项目)。在实践中,可疑分支/Xid 的数量足够小,以至于它们仅形成一个批处理,因此许多 TM 将简单地调用 TMSTARTRSCAN,然后直接调用 TMENDRSCAN,甚至在一次调用中同时执行这两个操作。理论上,这可能会错过一些有疑问的分支,但通常效果很好,因为调用周期会定期重复,并且任何额外的分支都会在下一次传递中被拾取。

RM将recover实现为稳定的游标/迭代器,从而满足迭代过程中事物不会发生太大变化的要求。同时它可以选择将有疑问的 tx 分支分成批处理,例如最大限度地减少驱动程序中的内存使用,由于上述原因,这不是常见的优化。

关于java - 如何正确使用JTA资源回收方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60570952/

相关文章:

Java:实例双数组元素值修改问题

java - 应用程序在使用线程时只是卡在中间?

java - JTA XAResource多个数据库: what if two phase commit fails after prepare

spring - 多(Tomcat + ActiveMQ + Mysql)事务管理

java - JMeter "Do it right"

java - 什么是 NullPointerException,我该如何解决?

java - 在事务中将消息发布到远程 TIBCO JMS 提供程序

java - 如何暂时禁用Hibernate实体版本检查?

java - 处理不同 EAR 上的交易

java - 如何让手机锁屏时屏幕显示闹钟