예제 #1
0
        override public void Open()
        {
            if (StatisticsEnabled)
            {
                if (null == _statistics)
                {
                    _statistics = new SqlStatistics();
                }
                else
                {
                    _statistics.ContinueOnNewConnection();
                }
            }

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                if (!TryOpen(null))
                {
                    throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending);
                }
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #2
0
        virtual internal SqlTransaction BeginSqlTransaction(IsolationLevel iso, string transactionName, bool shouldReconnect)
        {
            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Connection.Statistics);

                ValidateConnectionForExecute(null);

                if (HasLocalTransactionFromAPI)
                {
                    throw ADP.ParallelTransactionsNotSupported(Connection);
                }

                if (iso == IsolationLevel.Unspecified)
                {
                    iso = IsolationLevel.ReadCommitted; // Default to ReadCommitted if unspecified.
                }

                SqlTransaction transaction = new SqlTransaction(this, Connection, iso, AvailableInternalTransaction);
                transaction.InternalTransaction.RestoreBrokenConnection = shouldReconnect;
                ExecuteTransaction(TransactionRequest.Begin, transactionName, iso, transaction.InternalTransaction, false);
                transaction.InternalTransaction.RestoreBrokenConnection = false;
                return(transaction);
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #3
0
 public override void ChangeDatabase(string database)
 {
     SNIHandle target = null;
     SqlStatistics statistics = null;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         target = SqlInternalConnection.GetBestEffortCleanupTarget(this);
         statistics = SqlStatistics.StartTimer(this.Statistics);
         this.InnerConnection.ChangeDatabase(database);
     }
     catch (OutOfMemoryException exception3)
     {
         this.Abort(exception3);
         throw;
     }
     catch (StackOverflowException exception2)
     {
         this.Abort(exception2);
         throw;
     }
     catch (ThreadAbortException exception)
     {
         this.Abort(exception);
         SqlInternalConnection.BestEffortCleanup(target);
         throw;
     }
     finally
     {
         SqlStatistics.StopTimer(statistics);
     }
 }
        public void WriteToServer(DataRow[] rows)
        {
            SqlConnection.ExecutePermission.Demand();
            SqlStatistics statistics = this.Statistics;

            try
            {
                statistics = SqlStatistics.StartTimer(this.Statistics);
                if (rows == null)
                {
                    throw new ArgumentNullException("rows");
                }
                if (rows.Length != 0)
                {
                    DataTable table = rows[0].Table;
                    this._rowState  = 0;
                    this._rowSource = rows;
                    this._SqlDataReaderRowSource = null;
                    this._rowSourceType          = ValueSourceType.RowArray;
                    this._rowEnumerator          = rows.GetEnumerator();
                    this.WriteRowSourceToServer(table.Columns.Count);
                }
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #5
0
        public SqlTransaction BeginTransaction(IsolationLevel iso, string transactionName)
        {
            WaitForPendingReconnection();
            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                SqlTransaction transaction;
                bool           isFirstAttempt = true;
                do
                {
                    transaction = GetOpenTdsConnection().BeginSqlTransaction(iso, transactionName, isFirstAttempt); // do not reconnect twice
                    Debug.Assert(isFirstAttempt || !transaction.InternalTransaction.ConnectionHasBeenRestored, "Restored connection on non-first attempt");
                    isFirstAttempt = false;
                } while (transaction.InternalTransaction.ConnectionHasBeenRestored);


                //  The GetOpenConnection line above doesn't keep a ref on the outer connection (this),
                //  and it could be collected before the inner connection can hook it to the transaction, resulting in
                //  a transaction with a null connection property.  Use GC.KeepAlive to ensure this doesn't happen.
                GC.KeepAlive(this);

                return(transaction);
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #6
0
        override public void Rollback()
        {
            if (IsYukonPartialZombie)
            {
                // Put something in the trace in case a customer has an issue
                _internalTransaction = null; // yukon zombification
            }
            else
            {
                ZombieCheck();

                SqlStatistics statistics = null;
                try
                {
                    statistics = SqlStatistics.StartTimer(Statistics);

                    _isFromAPI = true;

                    _internalTransaction.Rollback();
                }
                finally
                {
                    _isFromAPI = false;

                    SqlStatistics.StopTimer(statistics);
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC METHODS
        ////////////////////////////////////////////////////////////////////////////////////////

        override public void Commit()
        {
            SqlConnection.ExecutePermission.Demand(); // MDAC 81476

            ZombieCheck();

            SqlStatistics statistics = null;
            IntPtr        hscp;

            Bid.ScopeEnter(out hscp, "<sc.SqlTransaction.Commit|API> %d#", ObjectID);
            Bid.CorrelationTrace("<sc.SqlTransaction.Commit|API|Correlation> ObjectID%d#, ActivityID %ls", ObjectID);

            TdsParser bestEffortCleanupTarget = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif //DEBUG
                    bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
                    statistics = SqlStatistics.StartTimer(Statistics);

                    _isFromAPI = true;

                    _internalTransaction.Commit();
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException e) {
                _connection.Abort(e);
                throw;
            }
            catch (System.StackOverflowException e) {
                _connection.Abort(e);
                throw;
            }
            catch (System.Threading.ThreadAbortException e)  {
                _connection.Abort(e);
                SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                throw;
            }
            finally {
                _isFromAPI = false;

                SqlStatistics.StopTimer(statistics);
                Bid.ScopeLeave(ref hscp);
            }
        }
예제 #8
0
            internal void Retry(Task <DbConnectionInternal> retryTask)
            {
                _registration.Dispose();
                try
                {
                    SqlStatistics statistics = null;
                    try
                    {
                        statistics = SqlStatistics.StartTimer(_parent.Statistics);

                        if (retryTask.IsFaulted)
                        {
                            Exception e = retryTask.Exception.InnerException;
                            _parent.CloseInnerConnection();
                            _parent._currentCompletion = null;
                            _result.SetException(retryTask.Exception.InnerException);
                        }
                        else if (retryTask.IsCanceled)
                        {
                            _parent.CloseInnerConnection();
                            _parent._currentCompletion = null;
                            _result.SetCanceled();
                        }
                        else
                        {
                            bool result;
                            // protect continuation from races with close and cancel
                            lock (_parent.InnerConnection)
                            {
                                result = _parent.TryOpen(_retry);
                            }
                            if (result)
                            {
                                _parent._currentCompletion = null;
                                _result.SetResult(null);
                            }
                            else
                            {
                                _parent.CloseInnerConnection();
                                _parent._currentCompletion = null;
                                _result.SetException(ADP.ExceptionWithStackTrace(ADP.InternalError(ADP.InternalErrorCode.CompletedConnectReturnedPending)));
                            }
                        }
                    }
                    finally
                    {
                        SqlStatistics.StopTimer(statistics);
                    }
                }
                catch (Exception e)
                {
                    _parent.CloseInnerConnection();
                    _parent._currentCompletion = null;
                    _result.SetException(e);
                }
            }
예제 #9
0
        public override Task OpenAsync(CancellationToken cancellationToken)
        {
            PrepareStatisticsForNewConnection();

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                TaskCompletionSource <DbConnectionInternal> completion = new TaskCompletionSource <DbConnectionInternal>();
                TaskCompletionSource <object> result = new TaskCompletionSource <object>();

                if (cancellationToken.IsCancellationRequested)
                {
                    result.SetCanceled();
                    return(result.Task);
                }


                bool completed;

                try
                {
                    completed = TryOpen(completion);
                }
                catch (Exception e)
                {
                    result.SetException(e);
                    return(result.Task);
                }

                if (completed)
                {
                    result.SetResult(null);
                }
                else
                {
                    CancellationTokenRegistration registration = new CancellationTokenRegistration();
                    if (cancellationToken.CanBeCanceled)
                    {
                        registration = cancellationToken.Register(() => completion.TrySetCanceled());
                    }
                    OpenAsyncRetry retry = new OpenAsyncRetry(this, completion, result, registration);
                    _currentCompletion = new Tuple <TaskCompletionSource <DbConnectionInternal>, Task>(completion, result.Task);
                    completion.Task.ContinueWith(retry.Retry, TaskScheduler.Default);
                    return(result.Task);
                }

                return(result.Task);
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #10
0
 public override void Close()
 {
     IntPtr ptr;
     Bid.ScopeEnter(out ptr, "<sc.SqlConnection.Close|API> %d#", this.ObjectID);
     try
     {
         SqlStatistics statistics = null;
         SNIHandle target = null;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             target = SqlInternalConnection.GetBestEffortCleanupTarget(this);
             statistics = SqlStatistics.StartTimer(this.Statistics);
             lock (this.InnerConnection)
             {
                 this.InnerConnection.CloseConnection(this, this.ConnectionFactory);
             }
             if (this.Statistics != null)
             {
                 ADP.TimerCurrent(out this._statistics._closeTimestamp);
             }
         }
         catch (OutOfMemoryException exception3)
         {
             this.Abort(exception3);
             throw;
         }
         catch (StackOverflowException exception2)
         {
             this.Abort(exception2);
             throw;
         }
         catch (ThreadAbortException exception)
         {
             this.Abort(exception);
             SqlInternalConnection.BestEffortCleanup(target);
             throw;
         }
         finally
         {
             SqlStatistics.StopTimer(statistics);
         }
     }
     finally
     {
         SqlDebugContext context = this._sdc;
         this._sdc = null;
         Bid.ScopeLeave(ref ptr);
         if (context != null)
         {
             context.Dispose();
         }
     }
 }
예제 #11
0
 public override void Rollback()
 {
     if (this.IsYukonPartialZombie)
     {
         if (Bid.AdvancedOn)
         {
             Bid.Trace("<sc.SqlTransaction.Rollback|ADV> %d# partial zombie no rollback required\n", this.ObjectID);
         }
         this._internalTransaction = null;
     }
     else
     {
         IntPtr ptr;
         this.ZombieCheck();
         SqlStatistics statistics = null;
         Bid.ScopeEnter(out ptr, "<sc.SqlTransaction.Rollback|API> %d#", this.ObjectID);
         SNIHandle target = null;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             target          = SqlInternalConnection.GetBestEffortCleanupTarget(this._connection);
             statistics      = SqlStatistics.StartTimer(this.Statistics);
             this._isFromAPI = true;
             this._internalTransaction.Rollback();
         }
         catch (OutOfMemoryException exception3)
         {
             this._connection.Abort(exception3);
             throw;
         }
         catch (StackOverflowException exception2)
         {
             this._connection.Abort(exception2);
             throw;
         }
         catch (ThreadAbortException exception)
         {
             this._connection.Abort(exception);
             SqlInternalConnection.BestEffortCleanup(target);
             throw;
         }
         finally
         {
             this._isFromAPI = false;
             SqlStatistics.StopTimer(statistics);
             Bid.ScopeLeave(ref ptr);
         }
     }
 }
예제 #12
0
        override public void ChangeDatabase(string database)
        {
            SqlStatistics statistics = null;

            RepairInnerConnection();
            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);
                InnerConnection.ChangeDatabase(database);
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
        internal virtual SqlTransaction BeginSqlTransaction(System.Data.IsolationLevel iso, string transactionName)
        {
            SNIHandle      target     = null;
            SqlStatistics  statistics = null;
            SqlTransaction transaction2;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                target     = GetBestEffortCleanupTarget(this.Connection);
                statistics = SqlStatistics.StartTimer(this.Connection.Statistics);
                SqlConnection.ExecutePermission.Demand();
                this.ValidateConnectionForExecute(null);
                if (this.HasLocalTransactionFromAPI)
                {
                    throw ADP.ParallelTransactionsNotSupported(this.Connection);
                }
                if (iso == System.Data.IsolationLevel.Unspecified)
                {
                    iso = System.Data.IsolationLevel.ReadCommitted;
                }
                SqlTransaction transaction = new SqlTransaction(this, this.Connection, iso, this.AvailableInternalTransaction);
                this.ExecuteTransaction(TransactionRequest.Begin, transactionName, iso, transaction.InternalTransaction, false);
                return(transaction);
            }
            catch (OutOfMemoryException exception3)
            {
                this.Connection.Abort(exception3);
                throw;
            }
            catch (StackOverflowException exception2)
            {
                this.Connection.Abort(exception2);
                throw;
            }
            catch (ThreadAbortException exception)
            {
                this.Connection.Abort(exception);
                BestEffortCleanup(target);
                throw;
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
            return(transaction2);
        }
예제 #14
0
        public void Save(string savePointName)
        {
            ZombieCheck();

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                _internalTransaction.Save(savePointName);
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #15
0
        public override void Rollback()
        {
            Exception e           = null;
            Guid      operationId = s_diagnosticListener.WriteTransactionRollbackBefore(_isolationLevel, _connection, null);

            if (IsYukonPartialZombie)
            {
                // Put something in the trace in case a customer has an issue
                _internalTransaction = null; // yukon zombification
            }
            else
            {
                ZombieCheck();

                SqlStatistics statistics = null;
                try
                {
                    statistics = SqlStatistics.StartTimer(Statistics);

                    _isFromAPI = true;

                    _internalTransaction.Rollback();
                }
                catch (Exception ex)
                {
                    e = ex;
                    throw;
                }
                finally
                {
                    if (e != null)
                    {
                        s_diagnosticListener.WriteTransactionRollbackError(operationId, _isolationLevel, _connection, null, e);
                    }
                    else
                    {
                        s_diagnosticListener.WriteTransactionRollbackAfter(operationId, _isolationLevel, _connection, null);
                    }
                    _isFromAPI = false;

                    SqlStatistics.StopTimer(statistics);
                }
            }
        }
예제 #16
0
        public override void Commit()
        {
            IntPtr ptr;

            SqlConnection.ExecutePermission.Demand();
            this.ZombieCheck();
            SqlStatistics statistics = null;

            Bid.ScopeEnter(out ptr, "<sc.SqlTransaction.Commit|API> %d#", this.ObjectID);
            SNIHandle target = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                target          = SqlInternalConnection.GetBestEffortCleanupTarget(this._connection);
                statistics      = SqlStatistics.StartTimer(this.Statistics);
                this._isFromAPI = true;
                this._internalTransaction.Commit();
            }
            catch (OutOfMemoryException exception3)
            {
                this._connection.Abort(exception3);
                throw;
            }
            catch (StackOverflowException exception2)
            {
                this._connection.Abort(exception2);
                throw;
            }
            catch (ThreadAbortException exception)
            {
                this._connection.Abort(exception);
                SqlInternalConnection.BestEffortCleanup(target);
                throw;
            }
            finally
            {
                this._isFromAPI = false;
                SqlStatistics.StopTimer(statistics);
                Bid.ScopeLeave(ref ptr);
            }
        }
예제 #17
0
        override public void Open()
        {
            PrepareStatisticsForNewConnection();

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                if (!TryOpen(null))
                {
                    throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending);
                }
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #18
0
 public SqlTransaction BeginTransaction(System.Data.IsolationLevel iso, string transactionName)
 {
     SqlStatistics statistics = null;
     SqlTransaction transaction;
     IntPtr ptr;
     string str = ADP.IsEmpty(transactionName) ? "None" : transactionName;
     Bid.ScopeEnter(out ptr, "<sc.SqlConnection.BeginTransaction|API> %d#, iso=%d{ds.IsolationLevel}, transactionName='%ls'\n", this.ObjectID, (int) iso, str);
     try
     {
         statistics = SqlStatistics.StartTimer(this.Statistics);
         SqlTransaction transaction2 = this.GetOpenConnection().BeginSqlTransaction(iso, transactionName);
         GC.KeepAlive(this);
         transaction = transaction2;
     }
     finally
     {
         Bid.ScopeLeave(ref ptr);
         SqlStatistics.StopTimer(statistics);
     }
     return transaction;
 }
예제 #19
0
        ////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC METHODS
        ////////////////////////////////////////////////////////////////////////////////////////

        override public void Commit()
        {
            ZombieCheck();

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                _isFromAPI = true;

                _internalTransaction.Commit();
            }
            finally
            {
                _isFromAPI = false;

                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #20
0
        public void Rollback(string transactionName)
        {
            ZombieCheck();

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                _isFromAPI = true;

                _internalTransaction.Rollback(transactionName);
            }
            finally
            {
                _isFromAPI = false;

                SqlStatistics.StopTimer(statistics);
            }
        }
        public void WriteToServer(IDataReader reader)
        {
            SqlConnection.ExecutePermission.Demand();
            SqlStatistics statistics = this.Statistics;

            try
            {
                statistics = SqlStatistics.StartTimer(this.Statistics);
                if (reader == null)
                {
                    throw new ArgumentNullException("reader");
                }
                this._rowSource = reader;
                this._SqlDataReaderRowSource = this._rowSource as SqlDataReader;
                this._rowSourceType          = ValueSourceType.IDataReader;
                this.WriteRowSourceToServer(reader.FieldCount);
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #22
0
        override public void Open()
        {
            Guid operationId = s_diagnosticListener.WriteConnectionOpenBefore(this);

            PrepareStatisticsForNewConnection();

            SqlStatistics statistics = null;

            Exception e = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                TaskCompletionSource <DbConnectionInternal> completionSource = null;
                if (!TryOpen(isAsync: false, completionSource: ref completionSource))
                {
                    throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending);
                }
            }
            catch (Exception ex)
            {
                e = ex;
                throw;
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);

                if (e != null)
                {
                    s_diagnosticListener.WriteConnectionOpenError(operationId, this, e);
                }
                else
                {
                    s_diagnosticListener.WriteConnectionOpenAfter(operationId, this);
                }
            }
        }
예제 #23
0
        public void Rollback(string transactionName)
        {
            Exception e           = null;
            Guid      operationId = s_diagnosticListener.WriteTransactionRollbackBefore(_isolationLevel, _connection, transactionName);

            ZombieCheck();

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                _isFromAPI = true;

                _internalTransaction.Rollback(transactionName);
            }
            catch (Exception ex)
            {
                e = ex;
                throw;
            }
            finally
            {
                if (e != null)
                {
                    s_diagnosticListener.WriteTransactionRollbackError(operationId, _isolationLevel, _connection, transactionName, e);
                }
                else
                {
                    s_diagnosticListener.WriteTransactionRollbackAfter(operationId, _isolationLevel, _connection, transactionName);
                }

                _isFromAPI = false;

                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #24
0
        ////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC METHODS
        ////////////////////////////////////////////////////////////////////////////////////////

        public override void Commit()
        {
            Exception e           = null;
            Guid      operationId = s_diagnosticListener.WriteTransactionCommitBefore(_isolationLevel, _connection);

            ZombieCheck();

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                _isFromAPI = true;

                _internalTransaction.Commit();
            }
            catch (Exception ex)
            {
                e = ex;
                throw;
            }
            finally
            {
                if (e != null)
                {
                    s_diagnosticListener.WriteTransactionCommitError(operationId, _isolationLevel, _connection, e);
                }
                else
                {
                    s_diagnosticListener.WriteTransactionCommitAfter(operationId, _isolationLevel, _connection);
                }

                _isFromAPI = false;

                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #25
0
        override public void Close()
        {
            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                Task reconnectTask = _currentReconnectionTask;
                if (reconnectTask != null && !reconnectTask.IsCompleted)
                {
                    CancellationTokenSource cts = _reconnectionCancellationSource;
                    if (cts != null)
                    {
                        cts.Cancel();
                    }
                    AsyncHelper.WaitForCompletion(reconnectTask, 0, null, rethrowExceptions: false); // we do not need to deal with possible exceptions in reconnection
                    if (State != ConnectionState.Open)
                    {                                                                                // if we cancelled before the connection was opened
                        OnStateChange(DbConnectionInternal.StateChangeClosed);
                    }
                }
                CancelOpenAndWait();
                CloseInnerConnection();
                GC.SuppressFinalize(this);

                if (null != Statistics)
                {
                    ADP.TimerCurrent(out _statistics._closeTimestamp);
                }
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
        public void WriteToServer(DataTable table, DataRowState rowState)
        {
            SqlConnection.ExecutePermission.Demand();
            SqlStatistics statistics = this.Statistics;

            try
            {
                statistics = SqlStatistics.StartTimer(this.Statistics);
                if (table == null)
                {
                    throw new ArgumentNullException("table");
                }
                this._rowState  = rowState & ~DataRowState.Deleted;
                this._rowSource = table;
                this._SqlDataReaderRowSource = null;
                this._rowSourceType          = ValueSourceType.DataTable;
                this._rowEnumerator          = table.Rows.GetEnumerator();
                this.WriteRowSourceToServer(table.Columns.Count);
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #27
0
        virtual internal SqlTransaction BeginSqlTransaction(IsolationLevel iso, string transactionName, bool shouldReconnect)
        {
            SqlStatistics statistics = null;
            TdsParser     bestEffortCleanupTarget = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif //DEBUG
                    bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(Connection);
                    statistics = SqlStatistics.StartTimer(Connection.Statistics);

                    SqlConnection.ExecutePermission.Demand(); // MDAC 81476

                    ValidateConnectionForExecute(null);

                    if (HasLocalTransactionFromAPI)
                    {
                        throw ADP.ParallelTransactionsNotSupported(Connection);
                    }

                    if (iso == IsolationLevel.Unspecified)
                    {
                        iso = IsolationLevel.ReadCommitted; // Default to ReadCommitted if unspecified.
                    }

                    SqlTransaction transaction = new SqlTransaction(this, Connection, iso, AvailableInternalTransaction);
                    transaction.InternalTransaction.RestoreBrokenConnection = shouldReconnect;
                    ExecuteTransaction(TransactionRequest.Begin, transactionName, iso, transaction.InternalTransaction, false);
                    transaction.InternalTransaction.RestoreBrokenConnection = false;
                    return(transaction);
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException e) {
                Connection.Abort(e);
                throw;
            }
            catch (System.StackOverflowException e) {
                Connection.Abort(e);
                throw;
            }
            catch (System.Threading.ThreadAbortException e) {
                Connection.Abort(e);
                SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                throw;
            }
            finally {
                SqlStatistics.StopTimer(statistics);
            }
        }
예제 #28
0
        override public void Close()
        {
            ConnectionState previousState      = State;
            Guid            operationId        = default(Guid);
            Guid            clientConnectionId = default(Guid);

            // during the call to Dispose() there is a redundant call to
            // Close(). because of this, the second time Close() is invoked the
            // connection is already in a closed state. this doesn't seem to be a
            // problem except for logging, as we'll get duplicate Before/After/Error
            // log entries
            if (previousState != ConnectionState.Closed)
            {
                operationId = s_diagnosticListener.WriteConnectionCloseBefore(this);
                // we want to cache the ClientConnectionId for After/Error logging, as when the connection
                // is closed then we will lose this identifier
                //
                // note: caching this is only for diagnostics logging purposes
                clientConnectionId = ClientConnectionId;
            }

            SqlStatistics statistics = null;

            Exception e = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                Task reconnectTask = _currentReconnectionTask;
                if (reconnectTask != null && !reconnectTask.IsCompleted)
                {
                    CancellationTokenSource cts = _reconnectionCancellationSource;
                    if (cts != null)
                    {
                        cts.Cancel();
                    }
                    AsyncHelper.WaitForCompletion(reconnectTask, 0, null, rethrowExceptions: false); // we do not need to deal with possible exceptions in reconnection
                    if (State != ConnectionState.Open)
                    {                                                                                // if we cancelled before the connection was opened
                        OnStateChange(DbConnectionInternal.StateChangeClosed);
                    }
                }
                CancelOpenAndWait();
                CloseInnerConnection();
                GC.SuppressFinalize(this);

                if (null != Statistics)
                {
                    ADP.TimerCurrent(out _statistics._closeTimestamp);
                }
            }
            catch (Exception ex)
            {
                e = ex;
                throw;
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);

                // we only want to log this if the previous state of the
                // connection is open, as that's the valid use-case
                if (previousState != ConnectionState.Closed)
                {
                    if (e != null)
                    {
                        s_diagnosticListener.WriteConnectionCloseError(operationId, clientConnectionId, this, e);
                    }
                    else
                    {
                        s_diagnosticListener.WriteConnectionCloseAfter(operationId, clientConnectionId, this);
                    }
                }
            }
        }
        override public void Rollback()
        {
            if (IsYukonPartialZombie)
            {
                // Put something in the trace in case a customer has an issue
                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.SqlTransaction.Rollback|ADV> %d# partial zombie no rollback required\n", ObjectID);
                }
                _internalTransaction = null; // yukon zombification
            }
            else
            {
                ZombieCheck();

                SqlStatistics statistics = null;
                IntPtr        hscp;
                Bid.ScopeEnter(out hscp, "<sc.SqlTransaction.Rollback|API> %d#", ObjectID);
                Bid.CorrelationTrace("<sc.SqlTransaction.Rollback|API|Correlation> ObjectID%d#, ActivityID %ls\n", ObjectID);

                TdsParser bestEffortCleanupTarget = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
#if DEBUG
                    TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                    RuntimeHelpers.PrepareConstrainedRegions();
                    try {
                        tdsReliabilitySection.Start();
#else
                    {
#endif //DEBUG
                        bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
                        statistics = SqlStatistics.StartTimer(Statistics);

                        _isFromAPI = true;

                        _internalTransaction.Rollback();
                    }
#if DEBUG
                    finally {
                        tdsReliabilitySection.Stop();
                    }
#endif //DEBUG
                }
                catch (System.OutOfMemoryException e) {
                    _connection.Abort(e);
                    throw;
                }
                catch (System.StackOverflowException e) {
                    _connection.Abort(e);
                    throw;
                }
                catch (System.Threading.ThreadAbortException e)  {
                    _connection.Abort(e);
                    SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                    throw;
                }
                finally {
                    _isFromAPI = false;

                    SqlStatistics.StopTimer(statistics);
                    Bid.ScopeLeave(ref hscp);
                }
            }
        }
예제 #30
0
        public override Task OpenAsync(CancellationToken cancellationToken)
        {
            Guid operationId = s_diagnosticListener.WriteConnectionOpenBefore(this);

            PrepareStatisticsForNewConnection();

            SqlStatistics statistics = null;

            try
            {
                statistics = SqlStatistics.StartTimer(Statistics);

                TaskCompletionSource <DbConnectionInternal> completion = new TaskCompletionSource <DbConnectionInternal>();
                TaskCompletionSource <object> result = new TaskCompletionSource <object>();

                if (s_diagnosticListener.IsEnabled(SqlClientDiagnosticListenerExtensions.SqlAfterOpenConnection) ||
                    s_diagnosticListener.IsEnabled(SqlClientDiagnosticListenerExtensions.SqlErrorOpenConnection))
                {
                    result.Task.ContinueWith((t) =>
                    {
                        if (t.Exception != null)
                        {
                            s_diagnosticListener.WriteConnectionOpenError(operationId, this, t.Exception);
                        }
                        else
                        {
                            s_diagnosticListener.WriteConnectionOpenAfter(operationId, this);
                        }
                    }, TaskScheduler.Default);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    result.SetCanceled();
                    return(result.Task);
                }


                bool completed;

                try
                {
                    completed = TryOpen(completion);
                }
                catch (Exception e)
                {
                    s_diagnosticListener.WriteConnectionOpenError(operationId, this, e);
                    result.SetException(e);
                    return(result.Task);
                }

                if (completed)
                {
                    result.SetResult(null);
                }
                else
                {
                    CancellationTokenRegistration registration = new CancellationTokenRegistration();
                    if (cancellationToken.CanBeCanceled)
                    {
                        registration = cancellationToken.Register(s => ((TaskCompletionSource <DbConnectionInternal>)s).TrySetCanceled(), completion);
                    }
                    OpenAsyncRetry retry = new OpenAsyncRetry(this, completion, result, registration);
                    _currentCompletion = new Tuple <TaskCompletionSource <DbConnectionInternal>, Task>(completion, result.Task);
                    completion.Task.ContinueWith(retry.Retry, TaskScheduler.Default);
                    return(result.Task);
                }

                return(result.Task);
            }
            catch (Exception ex)
            {
                s_diagnosticListener.WriteConnectionOpenError(operationId, this, ex);
                throw;
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }