You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2010/08/11 18:54:28 UTC
svn commit: r984471 - in /geronimo/components/txmanager/trunk: ./
geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/
geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/
Author: djencks
Date: Wed Aug 11 16:54:28 2010
New Revision: 984471
URL: http://svn.apache.org/viewvc?rev=984471&view=rev
Log:
GERONIMO-5519 match up the xid with the name during recovery. Add some more tracing. Merge from 2.1 branch rev 984273
Modified:
geronimo/components/txmanager/trunk/ (props changed)
geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoverTask.java
geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java
geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionBranchInfoImpl.java
geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/AbstractRecoveryTest.java
geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/MockLog.java
geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/RecoveryTest.java
Propchange: geronimo/components/txmanager/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Aug 11 16:54:28 2010
@@ -1,2 +1,2 @@
-/geronimo/components/txmanager/branches/geronimo-txmanager-parent-2.1:780438-803185,984259,984262
+/geronimo/components/txmanager/branches/geronimo-txmanager-parent-2.1:780438-803185,984259,984262,984273
/geronimo/components/txmanager/branches/geronimo-txmanager-parent-2.1.1:981270
Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoverTask.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoverTask.java?rev=984471&r1=984470&r2=984471&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoverTask.java (original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoverTask.java Wed Aug 11 16:54:28 2010
@@ -43,7 +43,7 @@ public class RecoverTask implements Runn
this.recoverableTransactionManager = recoverableTransactionManager;
}
- @Override
+// @Override
public void run() {
try {
NamedXAResource namedXAResource = namedXAResourceFactory.getNamedXAResource();
Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java?rev=984471&r1=984470&r2=984471&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java (original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java Wed Aug 11 16:54:28 2010
@@ -74,9 +74,11 @@ public class RecoveryImpl implements Rec
}
for (XidBranchesPair xidBranchesPair : preparedXids) {
Xid xid = xidBranchesPair.getXid();
+ log.trace("read prepared global xid from log: " + toString(xid));
if (xidFactory.matchesGlobalId(xid.getGlobalTransactionId())) {
ourXids.put(new ByteArrayWrapper(xid.getGlobalTransactionId()), xidBranchesPair);
for (TransactionBranchInfo transactionBranchInfo : xidBranchesPair.getBranches()) {
+ log.trace("read branch from log: " + transactionBranchInfo.toString());
String name = transactionBranchInfo.getResourceName();
Set<XidBranchesPair> transactionsForName = nameToOurTxMap.get(name);
if (transactionsForName == null) {
@@ -86,6 +88,7 @@ public class RecoveryImpl implements Rec
transactionsForName.add(xidBranchesPair);
}
} else {
+ log.trace("read external prepared xid from log: " + toString(xid));
TransactionImpl externalTx = new ExternalTransaction(xid, txLog, retryScheduler, xidBranchesPair.getBranches());
externalXids.put(xid, externalTx);
externalGlobalIdMap.put(xid.getGlobalTransactionId(), externalTx);
@@ -99,6 +102,7 @@ public class RecoveryImpl implements Rec
Xid[] prepared = xaResource.recover(XAResource.TMSTARTRSCAN + XAResource.TMENDRSCAN);
for (int i = 0; prepared != null && i < prepared.length; i++) {
Xid xid = prepared[i];
+ log.trace("considering recovered xid from\n name: " + xaResource.getName() + "\n " + toString(xid));
ByteArrayWrapper globalIdWrapper = new ByteArrayWrapper(xid.getGlobalTransactionId());
XidBranchesPair xidNamesPair = ourXids.get(globalIdWrapper);
@@ -107,7 +111,8 @@ public class RecoveryImpl implements Rec
// 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)) {
+ if (isNameInTransaction(xidNamesPair, name, xid)) {
+ log.trace("This xid was prepared from this XAResource: committing");
try {
xaResource.commit(xid, false);
} catch(XAException e) {
@@ -115,9 +120,12 @@ public class RecoveryImpl implements Rec
log.error("Recovery error", e);
}
removeNameFromTransaction(xidNamesPair, name, true);
+ } else {
+ log.trace("This xid was prepared from another XAResource, ignoring");
}
} else if (xidFactory.matchesGlobalId(xid.getGlobalTransactionId())) {
//ours, but prepare not logged
+ log.trace("this xid was initiated from this tm but not prepared: rolling back");
try {
xaResource.rollback(xid);
} catch (XAException e) {
@@ -129,6 +137,7 @@ public class RecoveryImpl implements Rec
TransactionImpl externalTx = externalGlobalIdMap.get(xid.getGlobalTransactionId());
if (externalTx == null) {
//we did not prepare this branch, rollback.
+ log.trace("this xid is from an external transaction and was not prepared: rolling back");
try {
xaResource.rollback(xid);
} catch (XAException e) {
@@ -136,6 +145,7 @@ public class RecoveryImpl implements Rec
log.error("Could not roll back", e);
}
} else {
+ log.trace("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);
}
@@ -150,15 +160,21 @@ public class RecoveryImpl implements Rec
}
}
- private boolean isNameInTransaction(XidBranchesPair xidBranchesPair, String name) {
+ private boolean isNameInTransaction(XidBranchesPair xidBranchesPair, String name, Xid xid) {
for (TransactionBranchInfo transactionBranchInfo : xidBranchesPair.getBranches()) {
- if (name.equals(transactionBranchInfo.getResourceName())) {
+ if (name.equals(transactionBranchInfo.getResourceName()) && equals(xid, transactionBranchInfo.getBranchXid())) {
return true;
}
}
return false;
}
-
+
+ private boolean equals(Xid xid1, Xid xid2) {
+ return xid1.getFormatId() == xid1.getFormatId()
+ && Arrays.equals(xid1.getBranchQualifier(), xid2.getBranchQualifier())
+ && Arrays.equals(xid1.getGlobalTransactionId(), xid2.getGlobalTransactionId());
+ }
+
private void removeNameFromTransaction(XidBranchesPair xidBranchesPair, String name, boolean warn) {
int removed = 0;
for (Iterator branches = xidBranchesPair.getBranches().iterator(); branches.hasNext();) {
@@ -206,6 +222,28 @@ public class RecoveryImpl implements Rec
return new HashMap<Xid, TransactionImpl>(externalXids);
}
+ private static String toString(Xid xid) {
+ if (xid instanceof XidImpl) {
+ return xid.toString();
+ }
+ StringBuilder s = new StringBuilder();
+ s.append("[Xid:class=").append(xid.getClass().getSimpleName()).append(":globalId=");
+ byte[] globalId = xid.getGlobalTransactionId();
+ for (int i = 0; i < globalId.length; i++) {
+ s.append(Integer.toHexString(globalId[i]));
+ }
+ s.append(",length=").append(globalId.length);
+ s.append(",branchId=");
+ byte[] branchId = xid.getBranchQualifier();
+ for (int i = 0; i < branchId.length; i++) {
+ s.append(Integer.toHexString(branchId[i]));
+ }
+ s.append(",length=");
+ s.append(branchId.length);
+ s.append("]");
+ return s.toString();
+ }
+
private static class ByteArrayWrapper {
private final byte[] bytes;
private final int hashCode;
Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionBranchInfoImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionBranchInfoImpl.java?rev=984471&r1=984470&r2=984471&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionBranchInfoImpl.java (original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionBranchInfoImpl.java Wed Aug 11 16:54:28 2010
@@ -32,6 +32,8 @@ public class TransactionBranchInfoImpl i
private final String resourceName;
public TransactionBranchInfoImpl(Xid branchXid, String resourceName) {
+ if (resourceName == null) throw new NullPointerException("resourceName");
+ if (branchXid == null) throw new NullPointerException("branchXid");
this.branchXid = branchXid;
this.resourceName = resourceName;
}
@@ -43,4 +45,16 @@ public class TransactionBranchInfoImpl i
public String getResourceName() {
return resourceName;
}
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder("[Transaction branch:\n");
+ b.append(" name:").append(resourceName);
+ b.append("\n branchId: ");
+ for (byte i : branchXid.getBranchQualifier()) {
+ b.append(Integer.toHexString(i));
+ }
+ b.append("\n]\n");
+ return b.toString();
+ }
}
Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/AbstractRecoveryTest.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/AbstractRecoveryTest.java?rev=984471&r1=984470&r2=984471&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/AbstractRecoveryTest.java (original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/AbstractRecoveryTest.java Wed Aug 11 16:54:28 2010
@@ -49,8 +49,8 @@ public abstract class AbstractRecoveryTe
public void test2ResOnlineAfterRecoveryStart() throws Exception {
Xid[] xids = getXidArray(XID_COUNT);
- MockXAResource xares1 = new MockXAResource(RM1, xids);
- MockXAResource xares2 = new MockXAResource(RM2, xids);
+ MockXAResource xares1 = new MockXAResource(RM1);
+ MockXAResource xares2 = new MockXAResource(RM2);
MockTransactionInfo[] txInfos = makeTxInfos(xids);
addBranch(txInfos, xares1);
addBranch(txInfos, xares2);
@@ -89,9 +89,9 @@ public abstract class AbstractRecoveryTe
tmp.addAll(xids23List);
Xid[] xids3 = (Xid[]) tmp.toArray(new Xid[6]);
- MockXAResource xares1 = new MockXAResource(RM1, xids1);
- MockXAResource xares2 = new MockXAResource(RM2, xids2);
- MockXAResource xares3 = new MockXAResource(RM3, xids3);
+ MockXAResource xares1 = new MockXAResource(RM1);
+ MockXAResource xares2 = new MockXAResource(RM2);
+ MockXAResource xares3 = new MockXAResource(RM3);
MockTransactionInfo[] txInfos12 = makeTxInfos(xids12);
addBranch(txInfos12, xares1);
addBranch(txInfos12, xares2);
@@ -140,12 +140,13 @@ public abstract class AbstractRecoveryTe
return xids;
}
- private void addBranch(MockTransactionInfo[] txInfos, MockXAResource xaRes) {
+ private void addBranch(MockTransactionInfo[] txInfos, MockXAResource xaRes) throws XAException {
for (int i = 0; i < txInfos.length; i++) {
MockTransactionInfo txInfo = txInfos[i];
Xid globalXid = txInfo.globalXid;
Xid branchXid = xidFactory.createBranch(globalXid, branchCounter++);
- txInfo.branches.add(new MockTransactionBranchInfo(xaRes.getName(), branchXid));
+ xaRes.start(branchXid, 0);
+ txInfo.branches.add(new TransactionBranchInfoImpl(branchXid, xaRes.getName()));
}
}
@@ -161,13 +162,12 @@ public abstract class AbstractRecoveryTe
private static class MockXAResource implements NamedXAResource {
private final String name;
- private final Xid[] xids;
- private final List committed = new ArrayList();
- private final List rolledBack = new ArrayList();
+ private final List<Xid> xids = new ArrayList<Xid>();
+ private final List<Xid> committed = new ArrayList<Xid>();
+ private final List<Xid> rolledBack = new ArrayList<Xid>();
- public MockXAResource(String name, Xid[] xids) {
+ public MockXAResource(String name) {
this.name = name;
- this.xids = xids;
}
public String getName() {
@@ -197,7 +197,7 @@ public abstract class AbstractRecoveryTe
}
public Xid[] recover(int flag) throws XAException {
- return xids;
+ return xids.toArray(new Xid[xids.size()]);
}
public void rollback(Xid xid) throws XAException {
@@ -209,6 +209,7 @@ public abstract class AbstractRecoveryTe
}
public void start(Xid xid, int flags) throws XAException {
+ xids.add(xid);
}
public List getCommitted() {
@@ -232,21 +233,4 @@ public abstract class AbstractRecoveryTe
}
}
- private static class MockTransactionBranchInfo implements TransactionBranchInfo {
- private final String name;
- private final Xid branchXid;
-
- public MockTransactionBranchInfo(String name, Xid branchXid) {
- this.name = name;
- this.branchXid = branchXid;
- }
-
- public String getResourceName() {
- return name;
- }
-
- public Xid getBranchXid() {
- return branchXid;
- }
- }
}
Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/MockLog.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/MockLog.java?rev=984471&r1=984470&r2=984471&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/MockLog.java (original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/MockLog.java Wed Aug 11 16:54:28 2010
@@ -33,9 +33,9 @@ import javax.transaction.xa.Xid;
* */
public class MockLog implements TransactionLog {
- final Map prepared = new HashMap();
- final List committed = new ArrayList();
- final List rolledBack = new ArrayList();
+ final Map<Xid, Recovery.XidBranchesPair> prepared = new HashMap<Xid, Recovery.XidBranchesPair>();
+ final List<Xid> committed = new ArrayList<Xid>();
+ final List<Xid> rolledBack = new ArrayList<Xid>();
public void begin(Xid xid) throws LogException {
}
@@ -56,8 +56,8 @@ public class MockLog implements Transact
rolledBack.add(xid);
}
- public Collection recover(XidFactory xidFactory) throws LogException {
- Map copy = new HashMap(prepared);
+ public Collection<Recovery.XidBranchesPair> recover(XidFactory xidFactory) throws LogException {
+ Map<Xid, Recovery.XidBranchesPair> copy = new HashMap<Xid, Recovery.XidBranchesPair>(prepared);
copy.keySet().removeAll(committed);
copy.keySet().removeAll(rolledBack);
return copy.values();
Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/RecoveryTest.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/RecoveryTest.java?rev=984471&r1=984470&r2=984471&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/RecoveryTest.java (original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/test/java/org/apache/geronimo/transaction/manager/RecoveryTest.java Wed Aug 11 16:54:28 2010
@@ -40,6 +40,7 @@ public class RecoveryTest extends TestCa
private final String RM1 = "rm1";
private final String RM2 = "rm2";
private final String RM3 = "rm3";
+ private int count = 0;
public void testCommittedRMToBeRecovered() throws Exception {
MockLog mockLog = new MockLog();
@@ -48,7 +49,7 @@ public class RecoveryTest extends TestCa
// to recover. This means that the presumed abort protocol has failed
// right after the commit of the RM and before the force-write of the
// committed log record.
- MockXAResource xares1 = new MockXAResource(RM1, new Xid[0]);
+ MockXAResource xares1 = new MockXAResource(RM1);
MockTransactionInfo[] txInfos = makeTxInfos(xids);
addBranch(txInfos, xares1);
prepareLog(mockLog, txInfos);
@@ -58,7 +59,7 @@ public class RecoveryTest extends TestCa
assertTrue(recovery.getExternalXids().isEmpty());
assertTrue(!recovery.localRecoveryComplete());
recovery.recoverResourceManager(xares1);
- assertEquals(0, xares1.committed.size());
+ assertEquals(1, xares1.committed.size());
assertTrue(recovery.localRecoveryComplete());
}
@@ -66,8 +67,8 @@ public class RecoveryTest extends TestCa
public void test2ResOnlineAfterRecoveryStart() throws Exception {
MockLog mockLog = new MockLog();
Xid[] xids = getXidArray(3);
- MockXAResource xares1 = new MockXAResource(RM1, xids);
- MockXAResource xares2 = new MockXAResource(RM2, xids);
+ MockXAResource xares1 = new MockXAResource(RM1);
+ MockXAResource xares2 = new MockXAResource(RM2);
MockTransactionInfo[] txInfos = makeTxInfos(xids);
addBranch(txInfos, xares1);
addBranch(txInfos, xares2);
@@ -86,10 +87,12 @@ public class RecoveryTest extends TestCa
}
- private void addBranch(MockTransactionInfo[] txInfos, MockXAResource xaRes) {
+ private void addBranch(MockTransactionInfo[] txInfos, MockXAResource xaRes) throws XAException {
for (int i = 0; i < txInfos.length; i++) {
MockTransactionInfo txInfo = txInfos[i];
- txInfo.branches.add(new MockTransactionBranchInfo(xaRes.getName()));
+ Xid xid = xidFactory.createBranch(txInfo.globalXid, count++);
+ xaRes.start(xid, 0);
+ txInfo.branches.add(new TransactionBranchInfoImpl(xid, xaRes.getName()));
}
}
@@ -97,7 +100,7 @@ public class RecoveryTest extends TestCa
MockTransactionInfo[] txInfos = new MockTransactionInfo[xids.length];
for (int i = 0; i < xids.length; i++) {
Xid xid = xids[i];
- txInfos[i] = new MockTransactionInfo(xid, new ArrayList());
+ txInfos[i] = new MockTransactionInfo(xid, new ArrayList<TransactionBranchInfo>());
}
return txInfos;
}
@@ -123,9 +126,9 @@ public class RecoveryTest extends TestCa
tmp.addAll(xids23List);
Xid[] xids3 = (Xid[]) tmp.toArray(new Xid[6]);
- MockXAResource xares1 = new MockXAResource(RM1, xids1);
- MockXAResource xares2 = new MockXAResource(RM2, xids2);
- MockXAResource xares3 = new MockXAResource(RM3, xids3);
+ MockXAResource xares1 = new MockXAResource(RM1);
+ MockXAResource xares2 = new MockXAResource(RM2);
+ MockXAResource xares3 = new MockXAResource(RM3);
MockTransactionInfo[] txInfos12 = makeTxInfos(xids12);
addBranch(txInfos12, xares1);
addBranch(txInfos12, xares2);
@@ -174,13 +177,12 @@ public class RecoveryTest extends TestCa
private static class MockXAResource implements NamedXAResource {
private final String name;
- private final Xid[] xids;
- private final List committed = new ArrayList();
- private final List rolledBack = new ArrayList();
+ private final List<Xid> xids = new ArrayList<Xid>();
+ private final List<Xid> committed = new ArrayList<Xid>();
+ private final List<Xid> rolledBack = new ArrayList<Xid>();
- public MockXAResource(String name, Xid[] xids) {
+ public MockXAResource(String name) {
this.name = name;
- this.xids = xids;
}
public String getName() {
@@ -210,7 +212,7 @@ public class RecoveryTest extends TestCa
}
public Xid[] recover(int flag) throws XAException {
- return xids;
+ return xids.toArray(new Xid[xids.size()]);
}
public void rollback(Xid xid) throws XAException {
@@ -222,6 +224,7 @@ public class RecoveryTest extends TestCa
}
public void start(Xid xid, int flags) throws XAException {
+ xids.add(xid);
}
public List getCommitted() {
@@ -237,27 +240,12 @@ public class RecoveryTest extends TestCa
private static class MockTransactionInfo {
private Xid globalXid;
- private List branches;
+ private List<TransactionBranchInfo> branches;
- public MockTransactionInfo(Xid globalXid, List branches) {
+ public MockTransactionInfo(Xid globalXid, List<TransactionBranchInfo> branches) {
this.globalXid = globalXid;
this.branches = branches;
}
}
- private static class MockTransactionBranchInfo implements TransactionBranchInfo {
- private String name;
-
- public MockTransactionBranchInfo(String name) {
- this.name = name;
- }
-
- public String getResourceName() {
- return name;
- }
-
- public Xid getBranchXid() {
- return null;
- }
- }
}