【问题标题】:How to properly use JTA resource recovery method?如何正确使用JTA资源回收方法?
【发布时间】:2020-03-06 20:11:31
【问题描述】:

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

JavaDocs 只是说可能有 TMSTARTRSCANTMENDRSCANTMNOFLAGS 的标志值,但没有解释使用任何这些标志或其组合时会发生什么。

我已经梳理了 Glassfish 代码以了解他们可能对标志值所做的事情,但没有发现任何有用的东西。我看过 Artemis - 只有在使用单独的 TMSTARTRSCAN 标志时,它才会返回所有不完整的事务。 Postgres JDBC 几乎是一样的,除了TMSTARTRSCAN 可以和TMENDRSCAN 耦合,所有的东西都是一次调用返回的。

我认为这些标志存在的原因是为了对结果进行某种分页,以防有太多未完成的交易。所以,处理这个问题的正确方法是:

  • 拨打recover()TMSTARTRSCAN
  • TMNOFLAGS 调用recover(),直到结果数组为空
  • 致电recover()TMENDRSCAN

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

但我很想有人指出或解释它是如何运作的。

更新

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

【问题讨论】:

标签: java jta


【解决方案1】:

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

首先,重要的是要明确您是从事务管理器(实际调用恢复方法的组件)的角度进行操作,还是从资源管理器(实现它的组件)的角度进行操作。 Glassfish 是 TM,Artemis 和 Postgres 是 RM。

TM 调用以迭代方式恢复,从 TMSTARTRSCAN(打开一个新的迭代器,获取第一批结果)开始,可选地跟在 TMNOFLAGS 之后(检查更多的结果批次,直到一个返回为空,表明已经结束) 并以 TMENDRSCAN 终止(关闭迭代器,允许 RM 释放它持有的项目)。在实践中,不确定分支/Xid 的数量足够小,它们仅形成一个批次,因此许多 TM 会简单地调用 TMSTARTRSCAN,然后直接调用 TMENDRSCAN,或者甚至在一次调用中同时调用两者。从理论上讲,这可能会遗漏一些不确定的分支,但通常效果很好,因为调用周期会定期重复,并且任何额外的东西都会在下一次传递中被拾取。

RM将recover实现为一个稳定的游标/迭代器,这样它就可以满足在迭代过程中不会发生太多变化的要求。虽然它可以选择将不确定的 tx 分支拆分为批次,例如尽量减少驱动程序中的内存使用,由于上述原因,这不是常见的优化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 2018-04-16
    • 2013-03-05
    相关资源
    最近更新 更多