Hi Wladimir,
Thank you for your reproducer. It was very easy to use and fully demonstrated the problem.
Also, thank you for your interesting question. After having reviewed the XA specification, I think that the logic employed in ArjunaJTA takes advantage of some flexibility in the specs. Basically, it treats all possible xa_prepare()’s error codes in the same way. This choice comes from the knowledge that xa_rollback() should return XAER_NOTA when invoked with an XID that does not exist. As a consequence, Narayana calls xa_rollback() for all xa_prepare()’s error codes. Of course, there is an argument that Narayana shouldn’t call xa_rollback() for resource managers that already replied negatively to the `prepare` phase (from the XA spec: [Page 8 of the XA spec, section 2.3.1] “The TM does not issue Phase 2 requests to RMs that responded negatively in Phase 1. The TM does not need to record stably the decision to roll back nor the participants in a rolled back global transaction”). This would also save Narayana a useless invocation. The reason why Narayana uses this trick goes back to the days when not all RMs were XA compliant and ArjunaJTA had to deal with this situation (that’s why the code here). Nowadays, most resource managers are XA compliant so we could/should think about improving this part of Narayana’s code base. On the other hand, when invoking xa_rollback() on PostgreSQL’s resource manager, Narayana is receiving an XAER_RMERR, which is the wrong error code. That is why Narayana reports a heuristic completion (basically, Narayana thinks that it invoked rollback on the resource manager, which then returns XAER_RMERR, thus Narayana doesn’t know if the resource manager rolled back the txn’s branch or not; hence, the outcome is mixed heuristic). My plan is to open an issue in the pgjdbc community and discuss the need to return an XAER_NOTA error code intestate of XAER_RMERR. While we wait for a reply and the pgjdbc community decides what to do with their driver, I am working on an improvement of the Narayana’s codebase to optimise Narayana’s handling of the XA_RB* error code.