On working with com.arjuna.ats.internal.jdbc.DirectRecoverableConnection I found out that state is not saved correctly for the connection could be restored from the object store and recovered.
The issue happens to be in case the direct recoverable XAResource throws XAException.XAER_RMFAIL on commit. That means the resource is not ready to commit but recovery should retry. In case of the DirectRecoverableConnection the state should be serialized and then restored from object store and used for recovery.
XAResourceRecord#prepare causes the connection (_recoveryObject) is saved under object store but then if fails on commit happens the XAResourceRecord#removeConnection is called where _recoveryObject is set to null and now the BasicAction#phase2Commit on call of updateState (call if (!save_state(state, ObjectType.ANDPERSISTENT))) tries to update state but the recovery object is already null and the old prepare version is overriden by commit one which has already removed information that the object is directly recoverable.