CommittableTransaction.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / tx / System / Transactions / CommittableTransaction.cs / 1305376 / CommittableTransaction.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Transactions 
{ 
    using System;
    using System.Threading; 

    using System.Transactions.Diagnostics;

    ///  
    // When we serialize a CommittableTransaction, we specify the type OletxTransaction, so a CommittableTransaction never
    // actually gets deserialized. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2229:ImplementSerializationConstructors")] 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly")]
    [Serializable] 
    public sealed class CommittableTransaction : Transaction, IAsyncResult
    {
        internal bool completedSynchronously = false;
 
        // Create a transaction with defaults
        public CommittableTransaction( 
            ) : this( System.Transactions.TransactionManager.DefaultIsolationLevel, 
                      System.Transactions.TransactionManager.DefaultTimeout )
        { 
        }


        // Create a transaction with the given info 
        public CommittableTransaction(
            TimeSpan timeout 
            ) : this( System.Transactions.TransactionManager.DefaultIsolationLevel, timeout ) 
        {
        } 


        // Create a transaction with the given options
        public CommittableTransaction( 
            TransactionOptions options
            ) : this( options.IsolationLevel, options.Timeout) 
        { 
        }
 

        internal CommittableTransaction(
            IsolationLevel isoLevel,
            TimeSpan timeout 
            ) : base( isoLevel, (InternalTransaction)null )
        { 
            // object to use for synchronization rather than locking on a public object 
            this.internalTransaction = new InternalTransaction( timeout, this );
 
            // Because we passed null for the internal transaction to the base class, we need to
            // fill in the traceIdentifier field here.
            this.internalTransaction.cloneCount = 1;
            this.cloneId = 1; 
            if ( DiagnosticTrace.Information )
            { 
                TransactionCreatedTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), 
                    this.TransactionTraceId
                    ); 
            }
        }

 
        public IAsyncResult BeginCommit(
            AsyncCallback asyncCallback, 
            object asyncState 
            )
        { 
            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ),
                    "CommittableTransaction.BeginCommit" 
                    );
                TransactionCommitCalledTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), 
                    this.TransactionTraceId 
                    );
            } 

            if( Disposed )
            {
                throw new ObjectDisposedException( "Transaction" ); 
            }
 
            lock( this.internalTransaction ) 
            {
                if( this.complete ) 
                {
                    throw TransactionException.CreateTransactionCompletedException( SR.GetString( SR.TraceSourceLtm ) );
                }
 
                // this.complete will get set to true when the transaction enters a state that is
                // beyond Phase0. 
 
                this.internalTransaction.State.BeginCommit( this.internalTransaction, true, asyncCallback, asyncState );
            } 

            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), 
                    "CommittableTransaction.BeginCommit"
                    ); 
            } 

            return this; 
        }


        // Forward the commit to the state machine to take the appropriate action. 
        //
        ///  
        public void Commit() 
        {
            if ( DiagnosticTrace.Verbose ) 
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ),
                    "CommittableTransaction.Commit"
                    ); 
                TransactionCommitCalledTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ),
                    this.TransactionTraceId 
                    ); 
            }
 
            if( Disposed )
            {
                throw new ObjectDisposedException( "Transaction" );
            } 

            lock( this.internalTransaction ) 
            { 
                if( this.complete )
                { 
                    throw TransactionException.CreateTransactionCompletedException( SR.GetString( SR.TraceSourceLtm ) );
                }

                this.internalTransaction.State.BeginCommit( this.internalTransaction, false, null, null ); 

                // now that commit has started wait for the monitor on the transaction to know 
                // if the transaction is done. 
                do
                { 
                    if( this.internalTransaction.State.IsCompleted( this.internalTransaction ) )
                    {
                        break;
                    } 
                } while( System.Threading.Monitor.Wait( this.internalTransaction ));
 
                this.internalTransaction.State.EndCommit( this.internalTransaction ); 

            } 

            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), 
                    "CommittableTransaction.Commit"
                    ); 
            } 
        }
 

        internal override void InternalDispose()
        {
            if ( DiagnosticTrace.Verbose ) 
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), 
                    "IDisposable.Dispose" 
                    );
            } 

            if( Interlocked.Exchange( ref this.disposed, Transaction.disposedTrueValue ) == Transaction.disposedTrueValue )
            {
                return; 
            }
 
            if( this.internalTransaction.State.get_Status( this.internalTransaction ) == TransactionStatus.Active ) 
            {
                lock( this.internalTransaction ) 
                {
                    // Since this is the root transaction do state based dispose.
                    this.internalTransaction.State.DisposeRoot( this.internalTransaction );
                } 
            }
 
            // Attempt to clean up the internal transaction 
            long remainingITx = Interlocked.Decrement( ref this.internalTransaction.cloneCount );
            if( remainingITx == 0 ) 
            {
                this.internalTransaction.Dispose();
            }
 
            if ( DiagnosticTrace.Verbose )
            { 
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), 
                    "IDisposable.Dispose"
                    ); 
            }
        }

 
        public void EndCommit(
            IAsyncResult asyncResult 
            ) 
        {
            if ( DiagnosticTrace.Verbose ) 
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ),
                    "CommittableTransaction.EndCommit"
                    ); 
            }
 
            if( asyncResult != ((object)this) ) 
            {
                throw new ArgumentException( SR.GetString( SR.BadAsyncResult ), "asyncResult" ); 
            }

            lock( this.internalTransaction )
            { 
                do
                { 
                    if( this.internalTransaction.State.IsCompleted( this.internalTransaction )) 
                    {
                        break; 
                    }
                } while( System.Threading.Monitor.Wait( this.internalTransaction ));

                this.internalTransaction.State.EndCommit( this.internalTransaction ); 
            }
 
            if ( DiagnosticTrace.Verbose ) 
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), 
                    "CommittableTransaction.EndCommit"
                    );
            }
        } 

        object IAsyncResult.AsyncState 
        { 
            get
            { 
                return this.internalTransaction.asyncState;
            }
        }
 
        bool IAsyncResult.CompletedSynchronously
        { 
            get 
            {
                return this.completedSynchronously; 
            }
        }

        WaitHandle IAsyncResult.AsyncWaitHandle 
        {
            get 
            { 
                if( this.internalTransaction.asyncResultEvent == null )
                { 
                    lock( this.internalTransaction )
                    {
                        if( this.internalTransaction.asyncResultEvent == null )
                        { 
                            // Demand create an event that is already signaled if the transaction has completed.
                            ManualResetEvent temp = new ManualResetEvent( 
                                this.internalTransaction.State.get_Status( this.internalTransaction ) != TransactionStatus.Active 
                                );
                            Thread.MemoryBarrier(); 
                            this.internalTransaction.asyncResultEvent = temp;
                        }
                    }
                } 

                return this.internalTransaction.asyncResultEvent; 
            } 
        }
 
        bool IAsyncResult.IsCompleted
        {
            get
            { 
                lock( this.internalTransaction )
                { 
                    return this.internalTransaction.State.get_Status( this.internalTransaction ) != TransactionStatus.Active; 
                }
            } 
        }
    }
}
 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK