Software design and other ramblings RSS 2.0
# Wednesday, 06 May 2009

I've seen a few newsgroups with SSIS developers having difficulties enlisting in the active transaction with a custom Data Flow component in .NET. I recently had to do this to enable message queue operations to be performed within the active transaction for the package. Unfortunately the built in Message Queue task has no support for enlisting in the active transaction so a custom approach was required. I'm sure that most SSIS developers who have dabbled with custom components will have seen the following Microsoft.SqlServer.Dts.Pipeline.PipelineComponent class:

/// <summary>
/// Establishes a connection to a connection manager
/// </summary>
public virtual void AcquireConnections (object transaction)

This method can be overriden a custom component and used to establish any required connections. Now we know that SSIS uses DTC transactions and that MSMQ supports DTC but how do the two map together? What is the transaction object that we are passed in? There seems to be very little documentation on this subject available on the internet so I experimented with the debugger and found a way to map this through to .NET. The first stage is to convert the supplied object into a managed System.Transactions.Transaction object. This can be achieved with the following code:

/// <summary>
/// Get a <code>System.Transactions.Transaction</code> from a supplied COM transaction pointer
/// </summary>
public static Transaction GetTransactionFromCom(object comTransaction)
{
    Transaction managedTransaction = null;

    ITransaction transactionInterface = comTransaction as ITransaction;

    if (transactionInterface != null)
    {
        managedTransaction =
            TransactionInterop.GetTransactionFromDtcTransaction((IDtcTransaction)transactionInterface);
    }

    return managedTransaction;
}

Once the supplied COM transaction pointer has been converted to a managed Transaction object it can be used as normal with your .NET code. For message queue transactions this means setting the ambient transaction and sending/receiving messages using MessageQueueTransactionType.Automatic. For example:

// Save the current transaction
Transaction previousTransaction = Transaction.Current;

// Set the current ambient transaction
Transaction.Current = managedTransaction;

try
{
    using (MessageQueue queue = new MessageQueue(messageQueuePath))
    {
        queue.Send("Body", "Label", MessageQueueTransactionType.Automatic);
    }
}
finally
{
    Transaction.Current = previousTransaction;
}
Wednesday, 06 May 2009 21:04:57 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | C#
Top Cashback
TopCashback
Archive
<2009 May>
SunMonTueWedThuFriSat
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2017 Scott Hill

Sign In
Statistics
Total Posts: 8
This Year: 0
This Month: 0
This Week: 0
Comments: 2
All Content © 2017, Scott Hill