OleDbTransaction.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 / Data / System / Data / OleDb / OleDbTransaction.cs / 1305376 / OleDbTransaction.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.OleDb {
 
    using System.Data;
    using System.Data.Common;
    using System.Data.ProviderBase;
    using System.Diagnostics; 
    using System.Runtime.CompilerServices;
    using System.Runtime.ConstrainedExecution; 
    using System.Runtime.InteropServices; 
    using System.Threading;
 
    public sealed class OleDbTransaction : DbTransaction {

        private readonly OleDbTransaction _parentTransaction; // strong reference to keep parent alive
        private readonly System.Data.IsolationLevel _isolationLevel; 

        private WeakReference _nestedTransaction; // child transactions 
        private WrappedTransaction _transaction; 

        internal OleDbConnection _parentConnection; 

        private static int _objectTypeCount; // Bid counter
        internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);
 
        private sealed class WrappedTransaction : WrappedIUnknown {
 
            private bool _mustComplete; 

            internal WrappedTransaction(UnsafeNativeMethods.ITransactionLocal transaction, int isolevel, out OleDbHResult hr) : base(transaction) { 
                int transactionLevel = 0;
                Bid.Trace("\n");
                RuntimeHelpers.PrepareConstrainedRegions();
                try { } finally { 
                    hr = transaction.StartTransaction(isolevel, 0, IntPtr.Zero, out transactionLevel);
                    if (0 <= hr) { 
                        _mustComplete = true; 
                    }
                } 
                Bid.Trace(" %08X{HRESULT}\n", hr);
            }

            internal bool MustComplete { 
                get { return _mustComplete; }
            } 
 
            internal OleDbHResult Abort() {
                Debug.Assert(_mustComplete, "transaction already completed"); 
                OleDbHResult hr;
                bool mustRelease = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try { 
                    DangerousAddRef(ref mustRelease);
 
                    Bid.Trace(" handle=%p\n", base.handle); 
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try { } finally { 
                        hr = (OleDbHResult)NativeOledbWrapper.ITransactionAbort(DangerousGetHandle());
                        _mustComplete = false;
                    }
                    Bid.Trace(" %08X{HRESULT}\n", hr); 
                }
                finally { 
                    if (mustRelease) { 
                        DangerousRelease();
                    } 
                }
                return hr;
            }
 
            internal OleDbHResult Commit() {
                Debug.Assert(_mustComplete, "transaction already completed"); 
                OleDbHResult hr; 
                bool mustRelease = false;
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try {
                    DangerousAddRef(ref mustRelease);

                    Bid.Trace(" handle=%p\n", base.handle); 
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try { } finally { 
                        hr = (OleDbHResult)NativeOledbWrapper.ITransactionCommit(DangerousGetHandle()); 
                        if ((0 <= (int)hr) || (OleDbHResult.XACT_E_NOTRANSACTION == hr)) {
                            _mustComplete = false; 
                        }
                    }
                    Bid.Trace(" %08X{HRESULT}\n", hr);
                } 
                finally {
                    if (mustRelease) { 
                        DangerousRelease(); 
                    }
                } 
                return hr;
            }

            override protected bool ReleaseHandle() { 
                if (_mustComplete && (IntPtr.Zero != base.handle)) {
                    Bid.Trace(" handle=%p\n", base.handle); 
                    OleDbHResult hr = (OleDbHResult)NativeOledbWrapper.ITransactionAbort(base.handle); 
                    _mustComplete = false;
                    Bid.Trace(" %08X{HRESULT}\n", hr); 
                }
                return base.ReleaseHandle();
            }
        } 

        internal OleDbTransaction(OleDbConnection connection, OleDbTransaction transaction, IsolationLevel isolevel) { 
            OleDbConnection.VerifyExecutePermission(); 

            _parentConnection = connection; 
            _parentTransaction = transaction;

            switch(isolevel) {
            case IsolationLevel.Unspecified: // OLE DB doesn't support this isolevel on local transactions 
                isolevel = IsolationLevel.ReadCommitted;
                break; 
            case IsolationLevel.Chaos: 
            case IsolationLevel.ReadUncommitted:
            case IsolationLevel.ReadCommitted: 
            case IsolationLevel.RepeatableRead:
            case IsolationLevel.Serializable:
            case IsolationLevel.Snapshot:
                break; 
            default:
                throw ADP.InvalidIsolationLevel(isolevel); // MDAC 74269 
            } 
            _isolationLevel = isolevel;
        } 

        new public OleDbConnection Connection { // MDAC 66655
            get {
                return _parentConnection; 
            }
        } 
 
        override protected DbConnection DbConnection {
            get { 
                return Connection;
            }
        }
 
        override public IsolationLevel IsolationLevel {
            get { 
                if (null == _transaction) { 
                    throw ADP.TransactionZombied(this);
                } 
                return _isolationLevel;
            }
        }
 
        internal int ObjectID {
            get { 
                return _objectID; 
            }
        } 

        internal OleDbTransaction Parent {
            get {
                return _parentTransaction; 
            }
        } 
 
        public OleDbTransaction Begin(IsolationLevel isolevel) {
            OleDbConnection.ExecutePermission.Demand(); // MDAC 81476 

            IntPtr hscp;
            Bid.ScopeEnter(out hscp, " %d#, isolevel=%d{IsolationLevel}", ObjectID, (int)isolevel);
            try { 
                if (null == _transaction) {
                    throw ADP.TransactionZombied(this); 
                } 
                else if ((null != _nestedTransaction) && _nestedTransaction.IsAlive) {
                    throw ADP.ParallelTransactionsNotSupported(Connection); 
                }
                // either the connection will be open or this will be a zombie

                OleDbTransaction transaction = new OleDbTransaction(_parentConnection, this, isolevel); 
                _nestedTransaction = new WeakReference(transaction, false);
 
                UnsafeNativeMethods.ITransactionLocal wrapper = null; 
                try {
                    wrapper = (UnsafeNativeMethods.ITransactionLocal)_transaction.ComWrapper(); 
                    transaction.BeginInternal(wrapper);
                }
                finally {
                    if (null != wrapper) { 
                        Marshal.ReleaseComObject(wrapper);
                    } 
                } 
                return transaction;
            } 
            finally {
                Bid.ScopeLeave(ref hscp);
            }
        } 

        public OleDbTransaction Begin() { 
            return Begin(IsolationLevel.ReadCommitted); 
        }
 
        internal void BeginInternal(UnsafeNativeMethods.ITransactionLocal transaction) {
            OleDbHResult hr;
            _transaction = new WrappedTransaction(transaction, (int) _isolationLevel, out hr);
            if (hr < 0) { 
                _transaction.Dispose();
                _transaction = null; 
                ProcessResults(hr); 
            }
        } 

        override public void Commit() {
            OleDbConnection.ExecutePermission.Demand(); // MDAC 81476
 
            IntPtr hscp;
            Bid.ScopeEnter(out hscp, " %d#", ObjectID); 
            try { 
                if (null == _transaction) {
                    throw ADP.TransactionZombied(this); 
                }
                CommitInternal();
            }
            finally { 
                Bid.ScopeLeave(ref hscp);
            } 
        } 

        private void CommitInternal() { 
            if (null == _transaction) {
                return;
            }
            if (null != _nestedTransaction) { 
                OleDbTransaction transaction = (OleDbTransaction) _nestedTransaction.Target;
                if ((null != transaction) && _nestedTransaction.IsAlive) { 
                    transaction.CommitInternal(); 
                }
                _nestedTransaction = null; 
            }
            OleDbHResult hr = _transaction.Commit();
            if (!_transaction.MustComplete) {
                _transaction.Dispose(); 
                _transaction = null;
 
                DisposeManaged(); 
            }
            if (hr < 0) { 
                // if an exception is thrown, user can try to commit their transaction again
                ProcessResults(hr);
            }
        } 

        /*public OleDbCommand CreateCommand() { // MDAC 68309 
            OleDbCommand cmd = Connection.CreateCommand(); 
            cmd.Transaction = this;
            return cmd; 
        }

        IDbCommand IDbTransaction.CreateCommand() {
            return CreateCommand(); 
        }*/
 
        protected override void Dispose(bool disposing) { 
            if (disposing) {
                DisposeManaged(); 
                RollbackInternal(false);
            }
            base.Dispose(disposing);
        } 

        private void DisposeManaged() { 
            if (null != _parentTransaction) { 
                _parentTransaction._nestedTransaction = null;
                //_parentTransaction = null; 
            }
            else if (null != _parentConnection) { // MDAC 67287
                _parentConnection.LocalTransaction = null;
            } 
            _parentConnection = null;
        } 
 
        private void ProcessResults(OleDbHResult hr) {
            Exception e = OleDbConnection.ProcessResults(hr, _parentConnection, this); 
            if (null != e) { throw e; }
        }

        override public void Rollback() { 
            IntPtr hscp;
            Bid.ScopeEnter(out hscp, " %d#", ObjectID); 
            try { 
                if (null == _transaction) {
                    throw ADP.TransactionZombied(this); 
                }
                DisposeManaged();
                RollbackInternal(true); // no recover if this throws an exception
            } 
            finally {
                Bid.ScopeLeave(ref hscp); 
            } 
        }
 
        /*protected virtual*/internal OleDbHResult RollbackInternal(bool exceptionHandling) {
            OleDbHResult hr = 0;
            if (null != _transaction) {
                if (null != _nestedTransaction) { 
                    OleDbTransaction transaction = (OleDbTransaction) _nestedTransaction.Target;
                    if ((null != transaction) && _nestedTransaction.IsAlive) { 
                        hr = transaction.RollbackInternal(exceptionHandling); 
                        if (exceptionHandling && (hr < 0)) {
                            SafeNativeMethods.Wrapper.ClearErrorInfo(); 
                            return hr;
                        }
                    }
                    _nestedTransaction = null; 
                }
                hr = _transaction.Abort(); 
                _transaction.Dispose(); 
                _transaction = null;
                if (hr < 0) { 
                    if (exceptionHandling) {
                        ProcessResults(hr);
                    }
                    else { 
                        SafeNativeMethods.Wrapper.ClearErrorInfo();
                    } 
                } 
            }
            return hr; 
        }

        static internal OleDbTransaction TransactionLast(OleDbTransaction head) {
            if (null != head._nestedTransaction) { 
                OleDbTransaction current = (OleDbTransaction) head._nestedTransaction.Target;
                if ((null != current) && head._nestedTransaction.IsAlive) { 
                    return TransactionLast(current); 
                }
            } 
            return head;
        }

        static internal OleDbTransaction TransactionUpdate(OleDbTransaction transaction) { 
            if ((null != transaction) && (null == transaction._transaction)) {
                return null; 
            } 
            return transaction;
        } 
    }
}

// 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