diff --git a/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java b/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java index 2c41c4a1e4..258aa039ac 100644 --- a/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java +++ b/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java @@ -421,10 +421,13 @@ public int topLevelAbort() if (!_prepared) break; // just do the finally block case XAException.XA_HEURHAZ: + _heuristic = TwoPhaseOutcome.HEURISTIC_HAZARD; return TwoPhaseOutcome.HEURISTIC_HAZARD; case XAException.XA_HEURCOM: + _heuristic = TwoPhaseOutcome.HEURISTIC_COMMIT; return TwoPhaseOutcome.HEURISTIC_COMMIT; case XAException.XA_HEURMIX: + _heuristic = TwoPhaseOutcome.HEURISTIC_MIXED; return TwoPhaseOutcome.HEURISTIC_MIXED; case XAException.XAER_NOTA: if (_recovered) @@ -532,6 +535,7 @@ public int topLevelCommit() switch (e1.errorCode) { case XAException.XA_HEURHAZ: + _heuristic = TwoPhaseOutcome.HEURISTIC_HAZARD; return TwoPhaseOutcome.HEURISTIC_HAZARD; case XAException.XA_HEURCOM: // what about forget? // OTS doesn't support @@ -548,14 +552,17 @@ public int topLevelCommit() case XAException.XA_RBTRANSIENT: case XAException.XAER_RMERR: case XAException.XAER_PROTO: // XA spec implies rollback + _heuristic = TwoPhaseOutcome.HEURISTIC_ROLLBACK; return TwoPhaseOutcome.HEURISTIC_ROLLBACK; case XAException.XA_HEURMIX: return TwoPhaseOutcome.HEURISTIC_MIXED; case XAException.XAER_NOTA: if (_recovered) break; // committed previously and recovery completed - else - return TwoPhaseOutcome.HEURISTIC_HAZARD; // something terminated the transaction! + else { + _heuristic = TwoPhaseOutcome.HEURISTIC_HAZARD; + return TwoPhaseOutcome.HEURISTIC_HAZARD; // something terminated the transaction! + } case XAException.XA_RETRY: case XAException.XAER_RMFAIL: _committed = true; // will cause log to be rewritten @@ -568,6 +575,7 @@ public int topLevelCommit() return TwoPhaseOutcome.FINISH_ERROR; case XAException.XAER_INVAL: // resource manager failed, did it rollback? default: + _heuristic = TwoPhaseOutcome.HEURISTIC_HAZARD; return TwoPhaseOutcome.HEURISTIC_HAZARD; } } @@ -775,6 +783,7 @@ public int topLevelOnePhaseCommit() { case XAException.XA_HEURHAZ: case XAException.XA_HEURMIX: + _heuristic = TwoPhaseOutcome.HEURISTIC_HAZARD; return TwoPhaseOutcome.HEURISTIC_HAZARD; case XAException.XA_HEURCOM: forget(); @@ -793,18 +802,21 @@ public int topLevelOnePhaseCommit() case XAException.XAER_RMERR: return TwoPhaseOutcome.ONE_PHASE_ERROR; case XAException.XAER_NOTA: + _heuristic = TwoPhaseOutcome.HEURISTIC_HAZARD; return TwoPhaseOutcome.HEURISTIC_HAZARD; // something committed or rolled back without asking us! // Some RMs do (or did) one-phase commit but interpreting end as prepare and once you’ve prepared (in end) you can commit or rollback when a timeout goes off // I *think* we’re talking about a while ago so those RMs may no longer exist. // The alternative implication is that the RM timed out the branch between the end above and the completion call, if we do make a change to assume that scenario // it is possible we could break existing deployments so changes should be considered and potentially configurable case XAException.XAER_INVAL: // resource manager failed, did it rollback? + _heuristic = TwoPhaseOutcome.HEURISTIC_HAZARD; return TwoPhaseOutcome.HEURISTIC_HAZARD; case XAException.XA_RETRY: // XA does not allow this to be thrown for 1PC! case XAException.XAER_PROTO: return TwoPhaseOutcome.ONE_PHASE_ERROR; // assume rollback case XAException.XAER_RMFAIL: // This was modified as part of JBTM-XYZ - although RMFAIL is not clear there is a rollback/commit we are flagging this to the user - return TwoPhaseOutcome.HEURISTIC_HAZARD; + _heuristic = TwoPhaseOutcome.HEURISTIC_HAZARD; + return TwoPhaseOutcome.HEURISTIC_HAZARD; default: _committed = true; // will cause log to be rewritten return TwoPhaseOutcome.FINISH_ERROR; // recovery should retry @@ -1363,6 +1375,10 @@ private boolean wasResourceContactedByRecoveryModule(final String jndiName) { return false; } + public int getHeuristic() { + return _heuristic; + } + public boolean isForgotten() { return _forgotten; } diff --git a/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBean.java b/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBean.java index 446363cf6a..87160b17cf 100644 --- a/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBean.java +++ b/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBean.java @@ -79,7 +79,6 @@ private void init() { public boolean activate() { boolean ok = super.activate(); - XAResource xares = (XAResource) rec.value(); className = rec.getClass().getName(); @@ -91,11 +90,13 @@ public boolean activate() { jndiName = xarec.getJndiName(); } - if (xares != null) { - className = xares.getClass().getName(); + if (rec.value() != null) { + XAResource xar = (XAResource) rec.value(); + + className = xar.getClass().getName(); try { - timeout = xares.getTransactionTimeout(); + timeout = xar.getTransactionTimeout(); } catch (Exception e) { } } @@ -164,6 +165,7 @@ public JTAXAResourceRecordWrapper(AbstractRecord rec) { this(rec.order()); this.rec = rec; this.xarec = (XAResourceRecord) rec; + heuristic = ((XAResourceRecord) rec).getHeuristic(); } @Override