in geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java [95:145]
public synchronized void recoverResourceManager(NamedXAResource xaResource) throws XAException {
String name = xaResource.getName();
Xid[] prepared = xaResource.recover(XAResource.TMSTARTRSCAN + XAResource.TMENDRSCAN);
for (int i = 0; prepared != null && i < prepared.length; i++) {
Xid xid = prepared[i];
if (xid.getGlobalTransactionId() == null || xid.getBranchQualifier() == null) {
log.log(Level.WARNING, "Ignoring bad xid from\n name: " + xaResource.getName() + "\n " + toString(xid));
continue;
}
log.log(Level.FINEST,"Considering recovered xid from\n name: " + xaResource.getName() + "\n " + toString(xid));
ByteArrayWrapper globalIdWrapper = new ByteArrayWrapper(xid.getGlobalTransactionId());
XidBranchesPair xidNamesPair = ourXids.get(globalIdWrapper);
if (xidNamesPair != null) {
// Only commit if this NamedXAResource was the XAResource for the transaction.
// Otherwise, wait for recoverResourceManager to be called for the actual XAResource
// This is a bit wasteful, but given our management of XAResources by "name", is about the best we can do.
if (isNameInTransaction(xidNamesPair, name, xid)) {
log.log(Level.FINEST,"This xid was prepared from this XAResource: committing");
commit(xaResource, xid);
removeNameFromTransaction(xidNamesPair, name, true);
} else {
log.log(Level.FINEST,"This xid was prepared from another XAResource, ignoring");
}
} else if (txManager.getXidFactory().matchesGlobalId(xid.getGlobalTransactionId())) {
//ours, but prepare not logged
log.log(Level.FINEST,"this xid was initiated from this tm but not prepared: rolling back");
rollback(xaResource, xid);
} else if (txManager.getXidFactory().matchesBranchId(xid.getBranchQualifier())) {
//our branch, but we did not start this tx.
TransactionImpl externalTx = externalGlobalIdMap.get(xid.getGlobalTransactionId());
if (externalTx == null) {
//we did not prepare this branch, rollback.
log.log(Level.FINEST,"this xid is from an external transaction and was not prepared: rolling back");
rollback(xaResource, xid);
} else {
log.log(Level.FINEST,"this xid is from an external transaction and was prepared in this tm. Waiting for instructions from transaction originator");
//we prepared this branch, must wait for commit/rollback command.
externalTx.addBranchXid(xaResource, xid);
}
}
//else we had nothing to do with this xid.
}
Set<XidBranchesPair> transactionsForName = nameToOurTxMap.get(name);
if (transactionsForName != null) {
for (XidBranchesPair xidBranchesPair : transactionsForName) {
removeNameFromTransaction(xidBranchesPair, name, false);
}
}
}