Transaction.Current and Ambient Transactions


Ambient transactions are defined as transactions that live in the current thread or object context that anybody interested can query for their existence and use them to do work as part of them. Their existence means that the user wants to do a series of actions in a transacted “all or nothing” way. They are not an enforcement, but merely a suggestion for the APIs that are going to be called. It is the API’s responsibility to use the transaction when one exists. We call these APIs, transaction-aware APIs. The main customers of these ambient transactions were and continue to be the database proxies (ODBC, OLEDB, System.Data). But with .Net Framework 2.0 and System.Transactions we expect this to change.


At first it was MTS (later called COM+) with its “object context” that could have a transaction present in it. In an MTS/COM+ component, you would have to call CoGetObjectContext with IID_IObjectContextInfo to obtain an IObjectContextInfo pointer and then to call IObjectContextInfo::GetTransaction to get the “current” transaction.


Later, System.EnterpriseServices continued this in .Net with its ambient transaction that could be accessed using System.EnterpriseServices.ContextUtil.Transaction. This transaction was available inside a ServicedComponent or a COM+ context created with SWC (Services Without Components – see also http://blogs.msdn.com/florinlazar/archive/2004/07/24/194199.aspx).


System.Transactions and TransactionScope has its own ambient transaction in Transaction.Current which is a static property that lives in the current thread local storage. System.Data was updated to be aware of this new ambient transaction. In fact, we did a lot of work to ensure seamless interoperability with System.EnterpriseServices, and now System.Data is only looking at Transaction.Current. Transaction.Current can detect that the transaction was created inside a COM+ context and provide it to anyone asking for the ambient transaction. If you are writing transaction-aware APIs for .Net Framework 2.0, the recommended ambient transaction to query and use is System.Transactions.Transaction.Current.

Comments (10)

  1. Florin, you mention that System.Data is aware of the new transactions, how far does that update go? Reason I ask is that the transaction Whitepaper states that ADO.NET has been updated to use System.Transactions…and that an LTM transaction to SQL Server 2005 will be as fast as a native SQL Server transaction, however, what is the situation with SQL Server 2000. From my testing when using SQL Server 2000 within a TransactionScope I can see a Distributed Transaction firing off – so, slower that ADO.NET Transactions. What I want to know is, is this the final behaviour or can we expect SQL Server 2000 perf within a TransactionScope to be equivalent to ADO.NET Local transaction perf?

  2. Scott,

    We provided the Promotable Single Phase Enlistment mechanism (http://pluralsight.com/wiki/default.aspx/Don/PromotableSinglePhaseEnlistment.html) for everyone to use. Currently only SQL Server 2005 takes advantage of it. This is mainly because you need support in the database server to allow this type of "promotable transactions". You will need to ask the SQL Server team if they plan on adding promotable transactions support in SQL Server 2000.

  3. Let me start with a quick story. I presented a while ago to some of my friends how cool System.Transactions…

  4. Yup, I knew about that – I really hope the SQL Server 2000 team does support this functionality though, if only because it will help with the adoption the System.Transactions over the old model (‘it’s not as fast’ stops a lot of people using a technology)

  5. Krishna says:

    Does the Beta 2 still depend on DTC for local transactions in case of SQL Server 2005 ? I am using Beta 2 with SQL April CTP and see that transactions are still going through DTC, Do you I need to set something up?

  6. Krishna says:

    Does the Beta 2 still depend on DTC for local transactions in case of SQL Server 2005 ? I am using Beta 2 with SQL April CTP and see that transactions are still going through DTC, Do you I need to set something up?

  7. florinlazar says:

    Krishna,

    If you open only one connection to SQL Server 2005, then DTC will not be involved.

  8. Erdem says:

    We are using a unitofwork which gets its on thread.if we want to have a transaction when we commit the unitofwork do we have to make a dependent transaction?

  9. florinlazar says:

    To: Erdem

    Yes, a "blocking" dependent transaction seems to be what you need.