我正在努力理解如何正确地调用javax.transaction.xa.XAResource.recovery(int)方法。我正在处理的环境中,我手动调用XA操作,并且没有容器资源管理器。
JavaDocs简单地说,可能存在TMSTARTRSCAN、TMENDRSCAN和TMNOFLAGS的标志值,但不要解释使用这些标志或它们的组合时会发生什么。
我已经梳理了玻璃鱼的代码,它们可能会使用标志值,但在那里没有发现任何有用的东西。我看过Artemis --只有在使用单独的TMSTARTRSCAN标志时,它才会返回所有不完整的事务。Postgres几乎是一样的,除了它的TMSTARTRSCAN可以与TMENDRSCAN耦合之外,所有的东西也是在一个调用中返回的。
我假设这些标志存在的原因是为了为结果提供某种分页,以防有太多未完成的事务出现。因此,正确的处理方法是:
使用TMSTARTRSCAN
recover()和TMNOFLAGS调用recover(),直到得到的数组为空的recover()和TMNOFLAGS为止对于所有上述调用,请准备好处理返回的XID值。
但我希望有人指出或解释这是如何发挥作用的。
更新
当@kayaman优雅地指出X/Open中的XA规范时,我可以看到我的假设可能是正确的。该标准更清楚地解释了预期的行为,但由于数组大小期望的不同,它没有将一对一应用于Java实现。该标准解释了何时不调用recover(TMENDRSCAN),但对于Java的情况则不清楚,也不清楚不正确地调用它是否会导致异常。
发布于 2020-03-10 09:57:48
这个JTA函数特别不直观,因为XA规范中的底层C API的许多设计细节在转换为Java时被屠杀了,因为在一种自动处理内存管理的语言中,它们并不完全正确。
首先,必须澄清您是从事务管理器(实际上调用恢复方法的组件)还是资源管理器(实现该方法的组件)的角度操作。Glassfish是商标,Artemis和Postgres是RMs。
TM调用以迭代方式恢复,从TMSTARTRSCAN (打开新的迭代器,获得第一批结果)开始,然后使用TMNOFLAGS (检查进一步的结果批次,直到返回为空,指示已到达)并以TMENDRSCAN结束(关闭迭代器,允许RM释放其持有的项)。实际上,存在疑问的分支/Xids的数量很小,它们只形成一个批,因此许多TMs只会调用TMENDRSCAN直接跟随TMENDRSCAN,甚至在单个调用中都调用。从理论上讲,这可能会错过一些有疑问的分支,但通常工作良好,因为调用周期是定期重复的,任何额外的部分都将在下一次测试中得到。
RM将恢复作为一个稳定的游标/迭代器来实现,这样它就满足了在迭代过程中事情不会有太多变化的要求。虽然它可以选择性地将怀疑的tx分支拆分成批,例如最小化驱动程序中的内存使用,但出于上述原因,这不是一个常见的优化。
https://stackoverflow.com/questions/60570952
复制相似问题