SqlConnection

public interface IDbConnection : IDisposable
{
        void Close();
        void Open();

        IDbTransaction BeginTransaction();
        IDbTransaction BeginTransaction(IsolationLevel il); 

        string ConnectionString { get; set;  }
 
        int ConnectionTimeout { get; }
        string Database { get; }
        ConnectionState State { get; }

        void ChangeDatabase(string databaseName);
        IDbCommand CreateCommand();
}

 

public abstract class DbConnection : Component, IDbConnection
{
       private StateChangeEventHandler _stateChangeEventHandler;
 
        protected DbConnection() : base() 
        {
        }

        abstract protected DbTransaction BeginDbTransaction(IsolationLevel isolationLevel);
 
        public DbTransaction BeginTransaction() 
        {
            return BeginDbTransaction(IsolationLevel.Unspecified);
        }
 
        public DbTransaction BeginTransaction(IsolationLevel isolationLevel)
        {
            return BeginDbTransaction(isolationLevel);
        }
 
        IDbTransaction IDbConnection.BeginTransaction() 
        {
            return BeginDbTransaction(IsolationLevel.Unspecified);
        }
 
        IDbTransaction IDbConnection.BeginTransaction(IsolationLevel isolationLevel) 
        {
            return BeginDbTransaction(isolationLevel);
        }
 abstract protected DbCommand CreateDbCommand();
 

        abstract public void Close();

        abstract public void Open();
 
        public Task OpenAsync() 
        {
            return OpenAsync(CancellationToken.None);
        }
public virtual Task OpenAsync(CancellationToken cancellationToken) { TaskCompletionSource<object> taskCompletionSource = new TaskCompletionSource<object>(); if (cancellationToken.IsCancellationRequested) { taskCompletionSource.SetCanceled(); } else { try { Open(); taskCompletionSource.SetResult(null); } catch (Exception e) { taskCompletionSource.SetException(e); } } return taskCompletionSource.Task; } }

 

public sealed partial class SqlConnection : DbConnection, ICloneable
{
    public SqlConnection(string connectionString)
        : this(connectionString, null)
    {
    }

    new public SqlTransaction BeginTransaction()
    {
        return BeginTransaction(IsolationLevel.Unspecified, null);
    }

    new public SqlTransaction BeginTransaction(IsolationLevel iso)
    {
        return BeginTransaction(iso, null);
    }

    public SqlTransaction BeginTransaction(string transactionName)
    {
        return BeginTransaction(IsolationLevel.Unspecified, transactionName);
    }

    static public void ClearAllPools()
    {
        (new SqlClientPermission(PermissionState.Unrestricted)).Demand();
        SqlConnectionFactory.SingletonInstance.ClearAllPools();
    }

    static public void ClearPool(SqlConnection connection)
    {
        ADP.CheckArgumentNull(connection, "connection");

        DbConnectionOptions connectionOptions = connection.UserConnectionOptions;
        if (null != connectionOptions)
        {
            connectionOptions.DemandPermission();
            if (connection.IsContextConnection)
            {
                throw SQL.NotAvailableOnContextConnection();
            }
            SqlConnectionFactory.SingletonInstance.ClearPool(connection);
        }
    }


    override public void Close()
    {
        IntPtr hscp;
        Bid.ScopeEnter(out hscp, "<sc.SqlConnection.Close|API> %d#", ObjectID);
        Bid.CorrelationTrace("<sc.SqlConnection.Close|API|Correlation> ObjectID%d#, ActivityID %ls\n", ObjectID);
        try
        {
            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(this);
                    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);
                        if (State != ConnectionState.Open)
                        {
                            OnStateChange(DbConnectionInternal.StateChangeClosed);
                        }
                    }
                    CancelOpenAndWait();
                    CloseInnerConnection();
                    GC.SuppressFinalize(this);

                    if (null != Statistics)
                    {
                        ADP.TimerCurrent(out _statistics._closeTimestamp);
                    }
                }
#if DEBUG
                    finally {
                        tdsReliabilitySection.Stop();
                    }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException e)
            {
                Abort(e);
                throw;
            }
            catch (System.StackOverflowException e)
            {
                Abort(e);
                throw;
            }
            catch (System.Threading.ThreadAbortException e)
            {
                Abort(e);
                SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                throw;
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
        finally
        {
            SqlDebugContext sdc = _sdc;
            _sdc = null;
            Bid.ScopeLeave(ref hscp);
            if (sdc != null)
            {
                sdc.Dispose();
            }
        }
    }


    private void DisposeMe(bool disposing)
    {
        _credential = null;
        _accessToken = null;

        if (!disposing)
        {
            var innerConnection = (InnerConnection as SqlInternalConnectionTds);
            if ((innerConnection != null) && (!innerConnection.ConnectionOptions.Pooling))
            {
                var parser = innerConnection.Parser;
                if ((parser != null) && (parser._physicalStateObj != null))
                {
                    parser._physicalStateObj.DecrementPendingCallbacks(release: false);
                }
            }
        }
    }


    override public void Open()
    {
        IntPtr hscp;
        Bid.ScopeEnter(out hscp, "<sc.SqlConnection.Open|API> %d#", ObjectID);
        Bid.CorrelationTrace("<sc.SqlConnection.Open|API|Correlation> ObjectID%d#, ActivityID %ls\n", ObjectID);

        try
        {
            if (StatisticsEnabled)
            {
                if (null == _statistics)
                {
                    _statistics = new SqlStatistics();
                }
                else
                {
                    _statistics.ContinueOnNewConnection();
                }
            }

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

                if (!TryOpen(null))
                {
                    throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending);
                }
            }
            finally
            {
                SqlStatistics.StopTimer(statistics);
            }
        }
        finally
        {
            Bid.ScopeLeave(ref hscp);
        }
    }


    public override Task OpenAsync(CancellationToken cancellationToken)
    {
        IntPtr hscp;
        Bid.ScopeEnter(out hscp, "<sc.SqlConnection.OpenAsync|API> %d#", ObjectID);
        Bid.CorrelationTrace("<sc.SqlConnection.OpenAsync|API|Correlation> ObjectID%d#, ActivityID %ls\n", ObjectID);
        try
        {
            if (StatisticsEnabled)
            {
                if (null == _statistics)
                {
                    _statistics = new SqlStatistics();
                }
                else
                {
                    _statistics.ContinueOnNewConnection();
                }
            }

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

                System.Transactions.Transaction transaction = ADP.GetCurrentTransaction();
                TaskCompletionSource<DbConnectionInternal> completion = new TaskCompletionSource<DbConnectionInternal>(transaction);
                TaskCompletionSource<object> result = new TaskCompletionSource<object>();

                if (cancellationToken.IsCancellationRequested)
                {
                    result.SetCanceled();
                    return result.Task;
                }
                if (IsContextConnection)
                {
                    result.SetException(ADP.ExceptionWithStackTrace(SQL.NotAvailableOnContextConnection()));
                    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);
            }
        }
        finally
        {
            Bid.ScopeLeave(ref hscp);
        }
    }

    public void ResetStatistics()
    {
        if (IsContextConnection)
        {
            throw SQL.NotAvailableOnContextConnection();
        }

        if (null != Statistics)
        {
            Statistics.Reset();
            if (ConnectionState.Open == State)
            {
                ADP.TimerCurrent(out _statistics._openTimestamp);
            }
        }
    }

    public IDictionary RetrieveStatistics()
    {
        if (IsContextConnection)
        {
            throw SQL.NotAvailableOnContextConnection();
        }

        if (null != Statistics)
        {
            UpdateStatistics();
            return Statistics.GetHashtable();
        }
        else
        {
            return new SqlStatistics().GetHashtable();
        }
    }
}

 

posted @ 2016-11-03 22:22  茗::流  阅读(368)  评论(0)    收藏  举报
如有雷同,纯属参考。如有侵犯你的版权,请联系我。