https://issues.apache.org/jira/browse/AMQNET-417
diff --git a/src/main/csharp/NetTxTransactionContext.cs b/src/main/csharp/NetTxTransactionContext.cs
index 1d0c6ca..214f32f 100644
--- a/src/main/csharp/NetTxTransactionContext.cs
+++ b/src/main/csharp/NetTxTransactionContext.cs
@@ -32,11 +32,22 @@
private const int XA_READONLY = 3;
private Enlistment currentEnlistment;
+ private static readonly Dictionary<string, bool> recoveredResourceManagerIds = new Dictionary<string, bool>();
public NetTxTransactionContext(Session session) : base(session)
{
}
+ /// <summary>
+ /// DTC recovery is performed once for each AppDomain per default. In case you want to perform
+ /// it again during execution of the application you can call this method before.
+ /// But ensure in this case that no connection is active anymore.
+ /// </summary>
+ public static void ResetDtcRecovery()
+ {
+ recoveredResourceManagerIds.Clear();
+ }
+
public override bool InLocalTransaction
{
get { return this.transactionId != null && this.currentEnlistment == null; }
@@ -500,62 +511,74 @@
/// </summary>
public void InitializeDtcTxContext()
{
+ string resourceManagerId = ResourceManagerId;
+
// initialize the logger with the current Resource Manager Id
- RecoveryLogger.Initialize(ResourceManagerId);
+ RecoveryLogger.Initialize(resourceManagerId);
- KeyValuePair<XATransactionId, byte[]>[] localRecoverables = RecoveryLogger.GetRecoverables();
- if (localRecoverables.Length == 0)
+ lock (recoveredResourceManagerIds)
{
- Tracer.Debug("Did not detect any open DTC transaction records on disk.");
- // No local data so anything stored on the broker can't be recovered here.
- return;
- }
-
- XATransactionId[] recoverables = TryRecoverBrokerTXIds();
- if (recoverables.Length == 0)
- {
- Tracer.Debug("Did not detect any recoverable transactions at Broker.");
- // Broker has no recoverable data so nothing to do here, delete the
- // old recovery log as its stale.
- RecoveryLogger.Purge();
- return;
- }
-
- List<KeyValuePair<XATransactionId, byte[]>> matches = new List<KeyValuePair<XATransactionId, byte[]>>();
-
- foreach (XATransactionId recoverable in recoverables)
- {
- foreach (KeyValuePair<XATransactionId, byte[]> entry in localRecoverables)
+ if (recoveredResourceManagerIds.ContainsKey(resourceManagerId))
{
- if (entry.Key.Equals(recoverable))
+ return;
+ }
+
+ recoveredResourceManagerIds[resourceManagerId] = true;
+
+ KeyValuePair<XATransactionId, byte[]>[] localRecoverables = RecoveryLogger.GetRecoverables();
+ if (localRecoverables.Length == 0)
+ {
+ Tracer.Debug("Did not detect any open DTC transaction records on disk.");
+ // No local data so anything stored on the broker can't be recovered here.
+ return;
+ }
+
+ XATransactionId[] recoverables = TryRecoverBrokerTXIds();
+ if (recoverables.Length == 0)
+ {
+ Tracer.Debug("Did not detect any recoverable transactions at Broker.");
+ // Broker has no recoverable data so nothing to do here, delete the
+ // old recovery log as its stale.
+ RecoveryLogger.Purge();
+ return;
+ }
+
+ List<KeyValuePair<XATransactionId, byte[]>> matches = new List<KeyValuePair<XATransactionId, byte[]>>();
+
+ foreach (XATransactionId recoverable in recoverables)
+ {
+ foreach (KeyValuePair<XATransactionId, byte[]> entry in localRecoverables)
{
- Tracer.DebugFormat("Found a matching TX on Broker to stored Id: {0} reenlisting.", entry.Key);
- matches.Add(entry);
+ if (entry.Key.Equals(recoverable))
+ {
+ Tracer.DebugFormat("Found a matching TX on Broker to stored Id: {0} reenlisting.", entry.Key);
+ matches.Add(entry);
+ }
}
}
- }
- if (matches.Count != 0)
- {
- this.recoveryComplete = new CountDownLatch(matches.Count);
-
- foreach (KeyValuePair<XATransactionId, byte[]> recoverable in matches)
+ if (matches.Count != 0)
{
- this.transactionId = recoverable.Key;
- Tracer.Info("Reenlisting recovered TX with Id: " + this.transactionId);
- this.currentEnlistment =
- TransactionManager.Reenlist(ResourceManagerGuid, recoverable.Value, this);
+ this.recoveryComplete = new CountDownLatch(matches.Count);
+
+ foreach (KeyValuePair<XATransactionId, byte[]> recoverable in matches)
+ {
+ this.transactionId = recoverable.Key;
+ Tracer.Info("Reenlisting recovered TX with Id: " + this.transactionId);
+ this.currentEnlistment =
+ TransactionManager.Reenlist(ResourceManagerGuid, recoverable.Value, this);
+ }
+
+ this.recoveryComplete.await();
+ Tracer.Debug("All Recovered TX enlistments Reports complete, Recovery Complete.");
+ TransactionManager.RecoveryComplete(ResourceManagerGuid);
+ return;
}
- this.recoveryComplete.await();
- Tracer.Debug("All Recovered TX enlistments Reports complete, Recovery Complete.");
- TransactionManager.RecoveryComplete(ResourceManagerGuid);
- return;
+ // The old recovery information doesn't match what's on the broker so we
+ // should discard it as its stale now.
+ RecoveryLogger.Purge();
}
-
- // The old recovery information doesn't match what's on the broker so we
- // should discard it as its stale now.
- RecoveryLogger.Purge();
}
private XATransactionId[] TryRecoverBrokerTXIds()
diff --git a/src/test/csharp/DtcConsumerTransactionsTest.cs b/src/test/csharp/DtcConsumerTransactionsTest.cs
index 706efa8..cbc1892 100644
--- a/src/test/csharp/DtcConsumerTransactionsTest.cs
+++ b/src/test/csharp/DtcConsumerTransactionsTest.cs
@@ -447,6 +447,7 @@
VerifyDatabaseTableIsFull();
// check messages are NOT present in the queue
+ NetTxTransactionContext.ResetDtcRecovery();
VerifyBrokerQueueCount(0, newConnectionUri);
Assert.AreEqual(0, Directory.GetFiles(logLocation).Length);
@@ -473,6 +474,7 @@
VerifyDatabaseTableIsEmpty();
// check messages are present in the queue
+ NetTxTransactionContext.ResetDtcRecovery();
VerifyBrokerQueueCount();
}
@@ -502,6 +504,7 @@
VerifyDatabaseTableIsEmpty();
// check messages are recovered and present in the queue
+ NetTxTransactionContext.ResetDtcRecovery();
VerifyBrokerQueueCount();
}
@@ -534,6 +537,7 @@
VerifyDatabaseTableIsEmpty();
// check messages are present in the queue
+ NetTxTransactionContext.ResetDtcRecovery();
VerifyBrokerQueueCount();
}
@@ -566,6 +570,7 @@
VerifyDatabaseTableIsEmpty();
// check messages are present in the queue
+ NetTxTransactionContext.ResetDtcRecovery();
VerifyBrokerQueueCount();
}
diff --git a/src/test/csharp/DtcProducerTransactionsTest.cs b/src/test/csharp/DtcProducerTransactionsTest.cs
index 494586b..b7ba963 100644
--- a/src/test/csharp/DtcProducerTransactionsTest.cs
+++ b/src/test/csharp/DtcProducerTransactionsTest.cs
@@ -66,6 +66,7 @@
VerifyDatabaseTableIsEmpty();
// check messages are present in the queue
+ NetTxTransactionContext.ResetDtcRecovery();
VerifyBrokerQueueCount();
}