Section 7.5. The Transaction Class


7.5. The Transaction Class

The transaction class from the System.Transactions namespace, introduced in .NET 2.0, represents the transaction all WCF transaction managers work with:

 [Serializable] public class Transaction : IDisposable,ISerializable {    public static Transaction Current    {get;set;}    public void Rollback( ); //Abort the transaction    public void Dispose( );    //More members } 

Developers rarely need to interact with the transaction class directly. The main use of the TRansaction class is to manually abort the transaction by calling the Rollback( ) method. Additional features of the transaction class include enlisting resource managers, setting the isolation level, subscribing to transaction events, cloning the transaction for concurrent threads, and obtaining transaction status and information.

7.5.1. The Ambient Transaction

.NET 2.0 defines a concept called an ambient transaction. The ambient transaction is the transaction in which your code executes. To obtain a reference to the ambient transaction, call the static Current property of transaction:

 Transaction ambientTransaction = Transaction.Current; 

If there is no ambient transaction, Current will return null. Every piece of code, be it client or service, can always reach out for its ambient transaction. The ambient transaction object is stored in the thread local storage (TLS). As a result, when the thread winds its way across multiple objects and methods on the same call chain, all objects and methods can access their ambient transactions.

In the context of WCF, the ambient transaction is paramount. When present, any WCF resource manager will automatically enlist in the ambient transaction. When a client calls a WCF service, if the client has an ambient transaction, and the binding and the contract are configured to allow transaction flow, the ambient transaction will propagate to the service.

The client cannot propagate an already aborted transaction to the service. Doing so will yield an exception.


7.5.2. Local Versus Distributed Transaction

The transaction class is used both for local and distributed transactions. Each transaction has two identifiers used to identify the local and the distributed transaction. You obtain the transaction identifiers by accessing the TRansactionInformation property of the transaction class:

 [Serializable] public class Transaction : IDisposable,ISerializable {    public TransactionInformation TransactionInformation    {get;}    //More members } 

The transactionInformation property is of the type transactionInformation defined as:

 public class TransactionInformation {    public Guid DistributedIdentifier    {get;}    public string LocalIdentifier    {get;}    //More members } 

transactionInformation offers access to the two identifiers. The main use of these identifiers is for logging, tracing, and analysis. In this chapter, I will use the identifiers as a convenient way to demonstrate transaction flow in code as a result of configuration.

7.5.2.1. Local transaction identifier

The local transaction identifier (local ID) contains both an identifier for the LTM in the current app domain as well as an ordinal number enumerating the transaction. You access the local ID via the LocalIdentifier property of transactionInformation. The local ID is always available with the ambient transaction, and as such is never null. As long as there is an ambient transaction, it will have a valid local ID. The value of the local ID has two parts to it: a constant GUID that is unique for each app domain representing the assigned LTM for that app domain, and an incremented integer enumerating the transactions managed so far by that LTM.

For example, if a service traces three consecutive transactions, starting with the first call, it would get something like:

 8947aec9-1fac-42bb-8de7-60df836e00d6:1 8947aec9-1fac-42bb-8de7-60df836e00d6:2 8947aec9-1fac-42bb-8de7-60df836e00d6:3 

The GUID is constant per app domain. If the service is hosted in the same app domain as the client, they will have the same GUID. If the client makes a cross-app domain call, the client will have its own unique GUID identifying its own local LTM.

7.5.2.2. Distributed transaction identifier

The distributed transaction identifier (distributed ID) is generated automatically whenever an LTM or KTM managed transaction is promoted to a DTC managed transaction (such as when the ambient transaction flows to another service). You access the distributed ID via the DistributedIdentifier property of transactionInformation. The distributed ID is unique per transaction, and no two transactions will ever have the same distributed ID. Most importantly, the distributed ID will be uniform across the service boundaries and across the entire call chain from the topmost client through every service and object down the call chain. As such, it is useful in logging and tracing. Note that the value of the distributed ID may be Guid.Empty when the transaction has not been promoted yet. The distributed ID is usually Guid.Empty on the client side when the client is the root of the transaction and the client did not call a service yet, and on the service side it will be empty if the service does not use the client's transaction and instead starts its own local transaction.




Programming WCF Services
Programming WCF Services
ISBN: 0596526997
EAN: 2147483647
Year: 2004
Pages: 148
Authors: Juval Lowy

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net