/** * If supplied xids contains any values seen on prev scans, replace the existing * XAResource with the supplied one and return true. Otherwise, return false. * * @param xaResource * @param xids * @return */ public boolean updateIfEquivalentRM(XAResource xaResource, Xid[] xids) { if(xids != null && xids.length > 0) { for(int i = 0; i < xids.length; i++) { if(contains(xids[i])) { _xares = xaResource; _lastValidated = System.currentTimeMillis(); return true; } } } // either (or both) passes have an empty Xid set, // so fallback to isSameRM as we can't use Xid matching if(isSameRM(xaResource)) { _xares = xaResource; _lastValidated = System.currentTimeMillis(); return true; } return false; }
/** * For some drivers, isSameRM is connection specific. If we have prev scan results * for the same RM but using a different connection, we need to be able to identify them. * Look at the data from previous scans, identify any for the same RM but different XAResource * by checking for matching Xids, then replace the old XAResource with the supplied one. * * @param xares * @param xids */ private void refreshXidScansForEquivalentXAResourceImpl(XAResource xares, Xid[] xids) { Set<XAResource> keys = new HashSet<XAResource>(_xidScans.keySet()); for(XAResource theKey : keys) { RecoveryXids recoveryXids = _xidScans.get(theKey); if(recoveryXids.updateIfEquivalentRM(xares, xids)) { // recoveryXids is for this xares, but was originally obtained using // a different XAResource. rekey the hashtable to use the new one. _xidScans.remove(theKey); _xidScans.put(xares, recoveryXids); } } }
private XAResource getTheKey(Xid xid) { if (_xidScans != null) { Enumeration<XAResource> keys = _xidScans.keys(); while (keys.hasMoreElements()) { XAResource theKey = keys.nextElement(); RecoveryXids xids = _xidScans.get(theKey); // JBTM-1255 moved stale check back to bottomUpRecovery if (xids.contains(xid)) { // This Xid is going to be recovered by the AtomicAction // it is possible that the Xid is recovered by both txbridge and XATerminator - the second // would get noxaresource error message xids.remove(xid); return theKey; } } } return null; }
RecoveryXids rxids = new RecoveryXids(tr); Xid[] xids = new XidImple[2]; xids[1] = new XidImple(new Uid()); RecoveryXids dup1 = new RecoveryXids(new DummyXA(false)); RecoveryXids dup2 = new RecoveryXids(tr); assertFalse(rxids.equals(dup1)); assertTrue(rxids.equals(dup2)); rxids.nextScan(xids); rxids.nextScan(xids); rxids.nextScan(xids); Object[] trans = rxids.toRecover(); assertEquals(0, trans.length); rxids.nextScan(xids); // force cleanup. trans = rxids.toRecover(); assertTrue(rxids.contains(xids[0])); assertFalse(rxids.updateIfEquivalentRM(new TestResource(), null)); assertTrue(rxids.updateIfEquivalentRM(new TestResource(), xids)); assertFalse(rxids.isSameRM(new TestResource()));
if (xidsToRecover.isSameRM(xares)) xidsToRecover = new RecoveryXids(xares); xidsToRecover.nextScan(trans);
if (xidsToRecover.isSameRM(xares)) xidsToRecover = new RecoveryXids(xares); xidsToRecover.nextScan(trans); Xid[] xids = xidsToRecover.toRecover();
if (xidsToRecover != null) { try { Xid[] xids = xidsToRecover.toRecover();
/** * * JBTM-895 garbage collection is now done when we return XAResources {@see XARecoveryModule#getNewXAResource(XAResourceRecord)} * @see XARecoveryModule#getNewXAResource(XAResourceRecord) */ private void bottomUpRecovery() { // scan using statically configured plugins; resourceInitiatedRecovery(); // scan using dynamically configured plugins: resourceInitiatedRecoveryForRecoveryHelpers(); // JBTM-895 garbage collection is now done when we return XAResources {@see XARecoveryModule#getNewXAResource(XAResourceRecord)} // JBTM-924 requires this here garbage collection, see JBTM-1155: if (_xidScans != null) { Set<XAResource> keys = new HashSet<XAResource>(_xidScans.keySet()); for(XAResource theKey : keys) { RecoveryXids recoveryXids = _xidScans.get(theKey); if(recoveryXids.isStale()) { _xidScans.remove(theKey); } } } }
/** * If supplied xids contains any values seen on prev scans, replace the existing * XAResource with the supplied one and return true. Otherwise, return false. * * @param xaResource * @param xids * @return */ public boolean updateIfEquivalentRM(XAResource xaResource, Xid[] xids) { if(xids == null || xids.length == 0) { return false; } for(int i = 0; i < xids.length; i++) { if(contains(xids[i])) { _xares = xaResource; return true; } } return false; }
/** * Check whether an XAResourceRecoveryHelper is currently being used by the scanner. * Must be called holding a lock on scanState * @param xaResourceRecoveryHelper the helper * @return true if the helper is in use */ private boolean isHelperInUse(XAResourceRecoveryHelper xaResourceRecoveryHelper) { XAResource[] xaResources = recoveryHelpersXAResource.get(xaResourceRecoveryHelper); if (xaResources != null) { for (int i = 0; i < xaResources.length; i++) { RecoveryXids recoveryXids = _xidScans.get(xaResources[i]); if (recoveryXids != null && recoveryXids.size() > 0) { return true; } } } return false; }
if (xidsToRecover.isSameRM(xares)) xidsToRecover = new RecoveryXids(xares); xidsToRecover.nextScan(trans); saveContactedJndiName(xares);
if (xidsToRecover.isSameRM(xares)) xidsToRecover = new RecoveryXids(xares); xidsToRecover.nextScan(trans); Object[] xids = xidsToRecover.toRecover();
if (xidsToRecover != null) { try { Xid[] xids = xidsToRecover.toRecover();
/** * * JBTM-895 garbage collection is now done when we return XAResources @see XARecoveryModule#getNewXAResource(XAResourceRecord) * @see XARecoveryModule#getNewXAResource(XAResourceRecord) */ private void bottomUpRecovery() { for (XAResource xaResource : _resources) { try { xaRecoverySecondPass(xaResource); } catch (Exception ex) { jtaLogger.i18NLogger.warn_recovery_getxaresource(ex); } } // JBTM-895 garbage collection is now done when we return XAResources {@see XARecoveryModule#getNewXAResource(XAResourceRecord)} // JBTM-924 requires this here garbage collection, see JBTM-1155: if (_xidScans != null) { Set<XAResource> keys = new HashSet<XAResource>(_xidScans.keySet()); for(XAResource theKey : keys) { RecoveryXids recoveryXids = _xidScans.get(theKey); if(recoveryXids.isStale()) { _xidScans.remove(theKey); } } } }
/** * @param xid The transaction to commit/rollback. * * @return the XAResource than can be used to commit/rollback the specified * transaction. */ private XAResource getNewXAResource(Xid xid) { if (_xidScans == null) { bottomUpRecovery(); } if (_xidScans != null) { Enumeration<XAResource> keys = _xidScans.keys(); while (keys.hasMoreElements()) { XAResource theKey = keys.nextElement(); RecoveryXids xids = _xidScans.get(theKey); // JBTM-1255 moved stale check back to bottomUpRecovery if (xids.contains(xid)) return theKey; } } return null; }
/** * Check whether an XAResourceRecoveryHelper is currently being used by the scanner. * Must be called holding a lock on scanState * @param xaResourceRecoveryHelper the helper * @return true if the helper is in use */ private boolean isHelperInUse(XAResourceRecoveryHelper xaResourceRecoveryHelper) { XAResource[] xaResources = recoveryHelpersXAResource.get(xaResourceRecoveryHelper); if (xaResources != null) { for (int i = 0; i < xaResources.length; i++) { RecoveryXids recoveryXids = _xidScans.get(xaResources[i]); if (recoveryXids != null && recoveryXids.size() > 0) { return true; } } } return false; }
if (xidsToRecover.isSameRM(xares)) xidsToRecover = new RecoveryXids(xares); xidsToRecover.nextScan(trans); saveContactedJndiName(xares);
private XAResource getTheKey(Xid xid) { if (_xidScans != null) { Enumeration<XAResource> keys = _xidScans.keys(); while (keys.hasMoreElements()) { XAResource theKey = keys.nextElement(); RecoveryXids xids = _xidScans.get(theKey); // JBTM-1255 moved stale check back to bottomUpRecovery if (xids.contains(xid)) { // This Xid is going to be recovered by the AtomicAction // it is possible that the Xid is recovered by both txbridge and XATerminator - the second // would get noxaresource error message xids.remove(xid); return theKey; } } } return null; }
/** * For some drivers, isSameRM is connection specific. If we have prev scan results * for the same RM but using a different connection, we need to be able to identify them. * Look at the data from previous scans, identify any for the same RM but different XAResource * by checking for matching Xids, then replace the old XAResource with the supplied one. * * @param xares * @param xids */ private void refreshXidScansForEquivalentXAResourceImpl(XAResource xares, Xid[] xids) { Set<XAResource> keys = new HashSet<XAResource>(_xidScans.keySet()); for(XAResource theKey : keys) { RecoveryXids recoveryXids = _xidScans.get(theKey); if(recoveryXids.updateIfEquivalentRM(xares, xids)) { // recoveryXids is for this xares, but was originally obtained using // a different XAResource. rekey the hashtable to use the new one. _xidScans.remove(theKey); _xidScans.put(xares, recoveryXids); _resources.remove(theKey); // There could be two datasources pointed at the same resource manager if (!_resources.contains(xares)) { _resources.add(xares); } } } }