Author: tabish
Date: Fri Mar 18 21:48:09 2011
New Revision: 1083083
URL: http://svn.apache.org/viewvc?rev=1083083&view=rev
Log:
Fix for https://issues.apache.org/jira/browse/AMQNET-321
Modified:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxConnection.cs
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxSession.cs
Modified:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxConnection.cs
URL:
http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxConnection.cs?rev=1083083&r1=1083082&r2=1083083&view=diff
==============================================================================
---
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxConnection.cs
(original)
+++
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxConnection.cs
Fri Mar 18 21:48:09 2011
@@ -16,6 +16,7 @@
*/
using System;
+using System.Transactions;
using Apache.NMS.ActiveMQ.Transport;
using Apache.NMS.ActiveMQ.Util;
@@ -42,6 +43,13 @@ namespace Apache.NMS.ActiveMQ
return (INetTxSession)
CreateSession(AcknowledgementMode.Transactional);
}
+ public INetTxSession CreateNetTxSession(Transaction tx)
+ {
+ NetTxSession session =
(NetTxSession)CreateSession(AcknowledgementMode.Transactional);
+ session.Enlist(tx);
+ return session;
+ }
+
protected override Session CreateAtiveMQSession(AcknowledgementMode
ackMode)
{
CheckConnected();
Modified:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxSession.cs
URL:
http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxSession.cs?rev=1083083&r1=1083082&r2=1083083&view=diff
==============================================================================
---
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxSession.cs
(original)
+++
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/branches/1.5.x/src/main/csharp/NetTxSession.cs
Fri Mar 18 21:48:09 2011
@@ -17,7 +17,6 @@
using System;
using System.Transactions;
-using Apache.NMS;
using Apache.NMS.ActiveMQ.Commands;
namespace Apache.NMS.ActiveMQ
@@ -31,6 +30,23 @@ namespace Apache.NMS.ActiveMQ
}
/// <summary>
+ /// Manually Enlists in the given Transaction. This can be used to
when the
+ /// client is using the Session in Asynchronous listener mode since
the Session
+ /// cannot atuomatically join in this case as there is no Ambient
transaction in
+ /// the Message Dispatch thread. This also allows for clients to use
the explicit
+ /// exception model when necessary.
+ /// </summary>
+ public void Enlist(Transaction tx)
+ {
+ if(tx == null)
+ {
+ throw new NullReferenceException("Specified Transaction cannot
be null");
+ }
+
+ this.EnrollInSpecifiedTransaction(tx);
+ }
+
+ /// <summary>
/// Reports Transacted whenever there is an Ambient Transaction or the
internal
/// TransactionContext is still involed in a .NET Transaction beyond
the lifetime
/// of an ambient transaction (can happen during a scoped transaction
disposing
@@ -61,20 +77,38 @@ namespace Apache.NMS.ActiveMQ
internal override void DoStartTransaction()
{
- if(!TransactionContext.InNetTransaction)
+ if(!TransactionContext.InNetTransaction && Transaction.Current !=
null)
{
- if(Transaction.Current != null)
- {
- Tracer.Debug("NetTxSession detected Ambient Transaction,
start new TX with broker");
-
- // Start a new .NET style transaction, this could be
distributed
- // or it could just be a Local transaction that could
become
- // distributed later.
- TransactionContext.Begin(Transaction.Current);
- }
+ Tracer.Debug("NetTxSession detected Ambient Transaction, start
new TX with broker");
+
+ EnrollInSpecifiedTransaction(Transaction.Current);
}
}
+ private void EnrollInSpecifiedTransaction(Transaction tx)
+ {
+ // If an Async DTC operation is in progress such as Commit or
Rollback
+ // we need to let it complete before deciding if the Session is in
a TX
+ // otherwise we might error out for no reason.
+
TransactionContext.DtcWaitHandle.WaitOne(TimeSpan.FromMilliseconds(1000), true);
+
+ if(TransactionContext.InNetTransaction)
+ {
+ Tracer.Warn("Enlist attempted while a Net TX was Active.");
+ throw new InvalidOperationException("Session is Already
enlisted in a Transaction");
+ }
+
+ if(Transaction.Current != null && !Transaction.Current.Equals(tx))
+ {
+ Tracer.Warn("Enlist attempted with a TX that doesn't match the
Ambient TX.");
+ throw new ArgumentException("Specified TX must match the
ambient TX if set.");
+ }
+
+ // Start a new .NET style transaction, this could be distributed
+ // or it could just be a Local transaction that could become
+ // distributed later.
+ TransactionContext.Begin(tx);
+ }
}
}