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.