protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
 {
     return new OleDbConnectionInternal((OleDbConnectionString) options, (OleDbConnection) owningObject);
 }
コード例 #2
0
 abstract protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection);
コード例 #3
0
 override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection) {
     return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection, userOptions: null);
 }
コード例 #4
0
        internal void MakePooledConnection(DbConnectionPool connectionPool) {
            // Used by DbConnectionFactory to indicate that this object IS part of
            // a connection pool.

            // 
            _createTime = DateTime.UtcNow; // WebData 111116

            _connectionPool = connectionPool;
            _performanceCounters = connectionPool.PerformanceCounters;
        }
コード例 #5
0
        internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
        {
            Debug.Assert(null != pool, "null pool?");
            DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo;

            DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions);
            if (null != newConnection)
            {
                newConnection.MakePooledConnection(pool);
            }
            return newConnection;
        }
コード例 #6
0
        internal void MakePooledConnection(DbConnectionPool connectionPool)
        {
            // Used by DbConnectionFactory to indicate that this object IS part of
            // a connection pool.
            _createTime = DateTime.UtcNow;

            _connectionPool = connectionPool;
        }
コード例 #7
0
        public virtual void Dispose()
        {
            _connectionPool = null;
            _performanceCounters = null;
            _connectionIsDoomed = true;
            _enlistedTransactionOriginal = null; // should not be disposed

            // Dispose of the _enlistedTransaction since it is a clone
            // of the original reference.
            // VSDD 780271 - _enlistedTransaction can be changed by another thread (TX end event)
            SysTx.Transaction enlistedTransaction = Interlocked.Exchange(ref _enlistedTransaction, null);
            if (enlistedTransaction != null)
            {
                enlistedTransaction.Dispose();
            }
        }
コード例 #8
0
        internal bool Prune()
        {
            // must only call from DbConnectionFactory.PruneConnectionPoolGroups on background timer thread
            // must lock(DbConnectionFactory._connectionPoolGroups.SyncRoot) before calling ReadyToRemove
            //     to avoid conflict with DbConnectionFactory.CreateConnectionPoolGroup replacing pool entry
            lock (this)
            {
                if (_poolCollection.Count > 0)
                {
                    var newPoolCollection = new ConcurrentDictionary <DbConnectionPoolIdentity, DbConnectionPool>();

                    foreach (var entry in _poolCollection)
                    {
                        DbConnectionPool pool = entry.Value;
                        if (pool != null)
                        {
                            //  Pruning a pool while a connection is currently attempting to connect
                            //  will cause the pool to be prematurely abandoned. The only known effect so
                            //  far is that the errorWait throttling will be reset when this occurs.
                            //  We should be able to avoid this situation by not pruning the pool if
                            //  it's _waitCount is non-zero (i.e. no connections *in* the pool, but also
                            //  no connections attempting to be created for the pool).

                            // Actually prune the pool if there are no connections in the pool and no errors occurred.
                            // Empty pool during pruning indicates zero or low activity, but
                            //  an error state indicates the pool needs to stay around to
                            //  throttle new connection attempts.
                            if ((!pool.ErrorOccurred) && (0 == pool.Count))
                            {
                                // Order is important here.  First we remove the pool
                                // from the collection of pools so no one will try
                                // to use it while we're processing and finally we put the
                                // pool into a list of pools to be released when they
                                // are completely empty.
                                DbConnectionFactory connectionFactory = pool.ConnectionFactory;

                                connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Decrement();
                                connectionFactory.QueuePoolForRelease(pool, false);
                            }
                            else
                            {
                                newPoolCollection.TryAdd(entry.Key, entry.Value);
                            }
                        }
                    }
                    _poolCollection = newPoolCollection;
                }

                // must be pruning thread to change state and no connections
                // otherwise pruning thread risks making entry disabled soon after user calls ClearPool
                if (0 == _poolCollection.Count)
                {
                    if (PoolGroupStateActive == _state)
                    {
                        _state = PoolGroupStateIdle;
                    }
                    else if (PoolGroupStateIdle == _state)
                    {
                        _state = PoolGroupStateDisabled;
                    }
                }
                return(PoolGroupStateDisabled == _state);
            }
        }
コード例 #9
0
        internal DbConnectionInternal CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
        {
            DbConnectionPoolGroupProviderInfo providerInfo = pool.PoolGroup.ProviderInfo;
            DbConnectionInternal internal2 = this.CreateConnection(options, providerInfo, pool, owningConnection);

            if (internal2 != null)
            {
                this.PerformanceCounters.HardConnectsPerSecond.Increment();
                internal2.MakePooledConnection(pool);
            }
            Bid.Trace("<prov.DbConnectionFactory.CreatePooledConnection|RES|CPOOL> %d#, Pooled database connection created.\n", this.ObjectID);
            return(internal2);
        }
コード例 #10
0
        internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
        {
            // The implementation here is the implementation required for the
            // "open" internal connections, since our own private "closed"
            // singleton internal connection objects override this method to
            // prevent anything funny from happening (like disposing themselves
            // or putting them into a connection pool)
            //
            // Derived class should override DbConnectionInternal.Deactivate and DbConnectionInternal.Dispose
            // for cleaning up after DbConnection.Close
            //     protected override void Deactivate() { // override DbConnectionInternal.Close
            //         // do derived class connection deactivation for both pooled & non-pooled connections
            //     }
            //     public override void Dispose() { // override DbConnectionInternal.Close
            //         // do derived class cleanup
            //         base.Dispose();
            //     }
            //
            // overriding DbConnection.Close is also possible, but must provider for their own synchronization
            //     public override void Close() { // override DbConnection.Close
            //         base.Close();
            //         // do derived class outer connection for both pooled & non-pooled connections
            //         // user must do their own synchronization here
            //     }
            //
            //     if the DbConnectionInternal derived class needs to close the connection it should
            //     delegate to the DbConnection if one exists or directly call dispose
            //         DbConnection owningObject = (DbConnection)Owner;
            //         if (null != owningObject) {
            //             owningObject.Close(); // force the closed state on the outer object.
            //         }
            //         else {
            //             Dispose();
            //         }
            //
            ////////////////////////////////////////////////////////////////
            // DON'T MESS WITH THIS CODE UNLESS YOU KNOW WHAT YOU'RE DOING!
            ////////////////////////////////////////////////////////////////
            Debug.Assert(null != owningObject, "null owningObject");
            Debug.Assert(null != connectionFactory, "null connectionFactory");


            // if an exception occurs after the state change but before the try block
            // the connection will be stuck in OpenBusy state.  The commented out try-catch
            // block doesn't really help because a ThreadAbort during the finally block
            // would just revert the connection to a bad state.
            // Open->Closed: guarantee internal connection is returned to correct pool
            if (connectionFactory.SetInnerConnectionFrom(owningObject, DbConnectionOpenBusy.SingletonInstance, this))
            {
                // Lock to prevent race condition with cancellation
                lock (this)
                {
                    object lockToken = ObtainAdditionalLocksForClose();
                    try
                    {
                        PrepareForCloseConnection();

                        DbConnectionPool connectionPool = Pool;


                        // The singleton closed classes won't have owners and
                        // connection pools, and we won't want to put them back
                        // into the pool.
                        if (null != connectionPool)
                        {
                            connectionPool.PutObject(this, owningObject);   // PutObject calls Deactivate for us...
                                                                            // NOTE: Before we leave the PutObject call, another
                                                                            // thread may have already popped the connection from
                                                                            // the pool, so don't expect to be able to verify it.
                        }
                        else
                        {
                            Deactivate();   // ensure we de-activate non-pooled connections, or the data readers and transactions may not get cleaned up...

                            // To prevent an endless recursion, we need to clear
                            // the owning object before we call dispose so that
                            // we can't get here a second time... Ordinarily, I
                            // would call setting the owner to null a hack, but
                            // this is safe since we're about to dispose the
                            // object and it won't have an owner after that for
                            // certain.
                            _owningObject.Target = null;

                            Dispose();
                        }
                    }
                    finally
                    {
                        ReleaseAdditionalLocksForClose(lockToken);
                        // if a ThreadAbort puts us here then its possible the outer connection will not reference
                        // this and this will be orphaned, not reclaimed by object pool until outer connection goes out of scope.
                        connectionFactory.SetInnerConnectionEvent(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
                    }
                }
            }
        }
コード例 #11
0
        internal DbConnectionPool?GetConnectionPool(DbConnectionFactory connectionFactory)
        {
            // When this method returns null it indicates that the connection
            // factory should not use pooling.

            // We don't support connection pooling on Win9x; it lacks too
            // many of the APIs we require.
            // PoolGroupOptions will only be null when we're not supposed to pool
            // connections.
            DbConnectionPool?pool = null;

            if (null != _poolGroupOptions)
            {
                Debug.Assert(ADP.IsWindowsNT, "should not be pooling on Win9x");

                DbConnectionPoolIdentity?currentIdentity = DbConnectionPoolIdentity.NoIdentity;
                if (_poolGroupOptions.PoolByIdentity)
                {
                    // if we're pooling by identity (because integrated security is
                    // being used for these connections) then we need to go out and
                    // search for the connectionPool that matches the current identity.

                    currentIdentity = DbConnectionPoolIdentity.GetCurrent();

                    // If the current token is restricted in some way, then we must
                    // not attempt to pool these connections.
                    if (currentIdentity.IsRestricted)
                    {
                        currentIdentity = null;
                    }
                }

                if (null != currentIdentity)
                {
                    if (!_poolCollection.TryGetValue(currentIdentity, out pool))
                    { // find the pool
                        lock (this)
                        {
                            // Did someone already add it to the list?
                            if (!_poolCollection.TryGetValue(currentIdentity, out pool))
                            {
                                DbConnectionPool newPool = new DbConnectionPool(connectionFactory, this, currentIdentity);

                                if (MarkPoolGroupAsActive())
                                {
                                    // If we get here, we know for certain that we there isn't
                                    // a pool that matches the current identity, so we have to
                                    // add the optimistically created one
                                    newPool.Startup(); // must start pool before usage
                                    bool addResult = _poolCollection.TryAdd(currentIdentity, newPool);
                                    Debug.Assert(addResult, "No other pool with current identity should exist at this point");
                                    connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Increment();
                                    pool = newPool;
                                }
                                else
                                {
                                    // else pool entry has been disabled so don't create new pools
                                    Debug.Assert(PoolGroupStateDisabled == _state, "state should be disabled");

                                    // don't need to call connectionFactory.QueuePoolForRelease(newPool) because
                                    // pool callbacks were delayed and no risk of connections being created
                                    newPool.Shutdown();
                                }
                            }
                            else
                            {
                                // else found an existing pool to use instead
                                Debug.Assert(PoolGroupStateActive == _state, "state should be active since a pool exists and lock holds");
                            }
                        }
                    }
                    // the found pool could be in any state
                }
            }

            if (null == pool)
            {
                lock (this)
                {
                    // keep the pool entry state active when not pooling
                    MarkPoolGroupAsActive();
                }
            }
            return(pool);
        }
コード例 #12
0
 virtual protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
 {
     return(CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection));
 }
 internal void QueuePoolForRelease(DbConnectionPool pool, bool clearing)
 {
     pool.Shutdown();
     lock (this._poolsToRelease)
     {
         if (clearing)
         {
             pool.Clear();
         }
         this._poolsToRelease.Add(pool);
     }
     this.PerformanceCounters.NumberOfInactiveConnectionPools.Increment();
 }
 internal DbConnectionInternal CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
 {
     DbConnectionPoolGroupProviderInfo providerInfo = pool.PoolGroup.ProviderInfo;
     DbConnectionInternal internal2 = this.CreateConnection(options, providerInfo, pool, owningConnection);
     if (internal2 != null)
     {
         this.PerformanceCounters.HardConnectsPerSecond.Increment();
         internal2.MakePooledConnection(pool);
     }
     Bid.Trace("<prov.DbConnectionFactory.CreatePooledConnection|RES|CPOOL> %d#, Pooled database connection created.\n", this.ObjectID);
     return internal2;
 }
コード例 #15
0
        internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactory) {
            // When this method returns null it indicates that the connection
            // factory should not use pooling.

            // We don't support connection pooling on Win9x; it lacks too
            // many of the APIs we require.
            // PoolGroupOptions will only be null when we're not supposed to pool
            // connections.
            DbConnectionPool pool = null;
            if (null != _poolGroupOptions) {
                Debug.Assert(ADP.IsWindowsNT, "should not be pooling on Win9x");

                DbConnectionPoolIdentity currentIdentity = DbConnectionPoolIdentity.NoIdentity;
                if (_poolGroupOptions.PoolByIdentity) {
                    // if we're pooling by identity (because integrated security is
                    // being used for these connections) then we need to go out and
                    // search for the connectionPool that matches the current identity.

                    currentIdentity = DbConnectionPoolIdentity.GetCurrent();

                    // If the current token is restricted in some way, then we must
                    // not attempt to pool these connections.
                    if (currentIdentity.IsRestricted) {
                        currentIdentity = null;
                    }
                }
                if (null != currentIdentity) {
                    if (!_poolCollection.TryGetValue(currentIdentity, out pool)) { // find the pool
                        DbConnectionPoolProviderInfo connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(this.ConnectionOptions);

                        // optimistically create pool, but its callbacks are delayed until after actual add
                        DbConnectionPool newPool = new DbConnectionPool(connectionFactory, this, currentIdentity, connectionPoolProviderInfo);

                        lock (this) {
                            // Did someone already add it to the list?
                            if (!_poolCollection.TryGetValue(currentIdentity, out pool)) {
                                if (MarkPoolGroupAsActive()) {
                                    // If we get here, we know for certain that we there isn't
                                    // a pool that matches the current identity, so we have to
                                    // add the optimistically created one
                                    newPool.Startup(); // must start pool before usage
                                    bool addResult = _poolCollection.TryAdd(currentIdentity, newPool);
                                    Debug.Assert(addResult, "No other pool with current identity should exist at this point");
#if !MOBILE
                                    connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Increment();
#endif
                                    pool = newPool;
                                    newPool = null;
                                }
                                else {
                                    // else pool entry has been disabled so don't create new pools
                                    Debug.Assert(PoolGroupStateDisabled == _state, "state should be disabled");
                                }
                            }
                            else {
                                // else found an existing pool to use instead
                                Debug.Assert(PoolGroupStateActive == _state, "state should be active since a pool exists and lock holds");
                            }
                        }

                        if (null != newPool) {
                            // don't need to call connectionFactory.QueuePoolForRelease(newPool) because
                            // pool callbacks were delayed and no risk of connections being created
                            newPool.Shutdown();
                        }
                    }
                    // the found pool could be in any state
                }
            }

            if (null == pool) {
                lock(this) {
                    // keep the pool entry state active when not pooling
                    MarkPoolGroupAsActive();
                }
            }
            return pool;
        }
コード例 #16
0
 protected abstract DbConnectionInternal CreateConnection(DbConnectionOptions options, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection);
コード例 #17
0
 public virtual void Dispose()
 {
     _connectionPool = null;
     _connectionIsDoomed = true;
 }
 internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactory)
 {
     object obj2 = null;
     if (this._poolGroupOptions != null)
     {
         DbConnectionPoolIdentity noIdentity = DbConnectionPoolIdentity.NoIdentity;
         if (this._poolGroupOptions.PoolByIdentity)
         {
             noIdentity = DbConnectionPoolIdentity.GetCurrent();
             if (noIdentity.IsRestricted)
             {
                 noIdentity = null;
             }
         }
         if (noIdentity != null)
         {
             obj2 = this._poolCollection[noIdentity];
             if (obj2 == null)
             {
                 DbConnectionPoolProviderInfo connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(this.ConnectionOptions);
                 DbConnectionPool pool = new DbConnectionPool(connectionFactory, this, noIdentity, connectionPoolProviderInfo);
                 lock (this)
                 {
                     HybridDictionary dictionary = this._poolCollection;
                     obj2 = dictionary[noIdentity];
                     if ((obj2 == null) && this.MarkPoolGroupAsActive())
                     {
                         pool.Startup();
                         HybridDictionary dictionary2 = new HybridDictionary(1 + dictionary.Count, false);
                         foreach (DictionaryEntry entry in dictionary)
                         {
                             dictionary2.Add(entry.Key, entry.Value);
                         }
                         dictionary2.Add(noIdentity, pool);
                         connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Increment();
                         this._poolCollection = dictionary2;
                         this._poolCount = dictionary2.Count;
                         obj2 = pool;
                         pool = null;
                     }
                 }
                 if (pool != null)
                 {
                     pool.Shutdown();
                 }
             }
         }
     }
     if (obj2 == null)
     {
         lock (this)
         {
             this.MarkPoolGroupAsActive();
         }
     }
     return (DbConnectionPool) obj2;
 }
コード例 #19
0
 protected override System.Data.ProviderBase.DbConnectionInternal CreateConnection(System.Data.Common.DbConnectionOptions options, object poolGroupProviderInfo, System.Data.ProviderBase.DbConnectionPool pool, DbConnection owningObject)
 {
     return(new OracleInternalConnection(options as OracleConnectionString));
 }
コード例 #20
0
 override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject) {
     DbConnectionInternal result = new OleDbConnectionInternal((OleDbConnectionString)options, (OleDbConnection)owningObject);
     return result;
 }
コード例 #21
0
        internal void MakeNonPooledObject(object owningObject, DbConnectionPoolCounters performanceCounters) {
            // Used by DbConnectionFactory to indicate that this object IS NOT part of
            // a connection pool.

            _connectionPool = null;
            _performanceCounters = performanceCounters;
            _owningObject.Target = owningObject;
            _pooledCount = -1;
        }
コード例 #22
0
        internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) {
            Debug.Assert(null != pool, "null pool?");
            DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo;

            DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions);
            if (null != newConnection) {
                PerformanceCounters.HardConnectsPerSecond.Increment();
                newConnection.MakePooledConnection(pool);
            }
            Bid.Trace("<prov.DbConnectionFactory.CreatePooledConnection|RES|CPOOL> %d#, Pooled database connection created.\n", ObjectID);
            return newConnection;
        }
コード例 #23
0
 override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject) {
     DbConnectionInternal result = new OdbcConnectionOpen(owningObject as OdbcConnection, options as OdbcConnectionString);
     return result;
 }
 public virtual void Dispose()
 {
     this._connectionPool = null;
     this._performanceCounters = null;
     this._connectionIsDoomed = true;
     this._enlistedTransactionOriginal = null;
     Transaction transaction = Interlocked.Exchange<Transaction>(ref this._enlistedTransaction, null);
     if (transaction != null)
     {
         transaction.Dispose();
     }
 }
コード例 #25
0
        internal void QueuePoolForRelease(DbConnectionPool pool, bool clearing)
        {
            // Queue the pool up for release -- we'll clear it out and dispose
            // of it as the last part of the pruning timer callback so we don't
            // do it with the pool entry or the pool collection locked.
            Debug.Assert(null != pool, "null pool?");

            // set the pool to the shutdown state to force all active
            // connections to be automatically disposed when they
            // are returned to the pool
            pool.Shutdown();

            lock (_poolsToRelease)
            {
                if (clearing)
                {
                    pool.Clear();
                }
                _poolsToRelease.Add(pool);
            }
        }
 internal void MakeNonPooledObject(object owningObject, DbConnectionPoolCounters performanceCounters)
 {
     this._connectionPool = null;
     this._performanceCounters = performanceCounters;
     this._owningObject.Target = owningObject;
     this._pooledCount = -1;
 }
コード例 #27
0
        // although the new password is generally not used it must be passed to the c'tor
        // the new Login7 packet will always write out the new password (or a length of zero and no bytes if not present)
        //
        internal SqlInternalConnectionTds(
                DbConnectionPoolIdentity    identity, 
                SqlConnectionString         connectionOptions,
                SqlCredential               credential,
                object                      providerInfo, 
                string                      newPassword,
                SecureString                newSecurePassword,
                bool                        redirectedUserInstance,
                SqlConnectionString         userConnectionOptions = null, // NOTE: userConnectionOptions may be different to connectionOptions if the connection string has been expanded (see SqlConnectionString.Expand)
                SessionData                 reconnectSessionData = null,
                DbConnectionPool            pool = null,
                string                      accessToken = null,
                bool applyTransientFaultHandling = false
                ) : base(connectionOptions) {

#if DEBUG
            if (reconnectSessionData != null) {
                reconnectSessionData._debugReconnectDataApplied = true;
            }
            try { // use this to help validate this object is only created after the following permission has been previously demanded in the current codepath
                if (userConnectionOptions != null) {
                    // As mentioned above, userConnectionOptions may be different to connectionOptions, so we need to demand on the correct connection string
                    userConnectionOptions.DemandPermission();
                }
                else {
                    connectionOptions.DemandPermission();
                }
            }
            catch(System.Security.SecurityException) {
                System.Diagnostics.Debug.Assert(false, "unexpected SecurityException for current codepath");
                throw;
            }
#endif
            Debug.Assert(reconnectSessionData == null || connectionOptions.ConnectRetryCount > 0, "Reconnect data supplied with CR turned off");

            _dbConnectionPool = pool;
  
            if (connectionOptions.ConnectRetryCount > 0) {
                _recoverySessionData = reconnectSessionData;          
                if (reconnectSessionData == null) {
                    _currentSessionData = new SessionData();
                }
                else {
                    _currentSessionData = new SessionData(_recoverySessionData);
                    _originalDatabase = _recoverySessionData._initialDatabase;
                    _originalLanguage = _recoverySessionData._initialLanguage;
                }
            }
          
            if (connectionOptions.UserInstance && InOutOfProcHelper.InProc) {
                throw SQL.UserInstanceNotAvailableInProc();
            }

            if (accessToken != null) {
                _accessTokenInBytes = System.Text.Encoding.Unicode.GetBytes(accessToken);
            }

            _identity = identity;
            Debug.Assert(newSecurePassword != null || newPassword != null, "cannot have both new secure change password and string based change password to be null");
            Debug.Assert(credential == null || (String.IsNullOrEmpty(connectionOptions.UserID) && String.IsNullOrEmpty(connectionOptions.Password)), "cannot mix the new secure password system and the connection string based password");

            Debug.Assert(credential == null || !connectionOptions.IntegratedSecurity, "Cannot use SqlCredential and Integrated Security");
            Debug.Assert(credential == null || !connectionOptions.ContextConnection, "Cannot use SqlCredential with context connection");

            _poolGroupProviderInfo = (SqlConnectionPoolGroupProviderInfo)providerInfo;
            _fResetConnection = connectionOptions.ConnectionReset;
            if (_fResetConnection && _recoverySessionData == null) {
                _originalDatabase = connectionOptions.InitialCatalog;
                _originalLanguage = connectionOptions.CurrentLanguage;
            }

            timeoutErrorInternal = new SqlConnectionTimeoutErrorInternal();
            _credential = credential;

            _parserLock.Wait(canReleaseFromAnyThread:false);
            ThreadHasParserLockForClose = true;   // In case of error, let ourselves know that we already own the parser lock
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif //DEBUG
                    _timeout = TimeoutTimer.StartSecondsTimeout(connectionOptions.ConnectTimeout);

                    // If transient fault handling is enabled then we can retry the login upto the ConnectRetryCount.
                    int connectionEstablishCount = applyTransientFaultHandling ? connectionOptions.ConnectRetryCount + 1 : 1;
                    int transientRetryIntervalInMilliSeconds = connectionOptions.ConnectRetryInterval * 1000; // Max value of transientRetryInterval is 60*1000 ms. The max value allowed for ConnectRetryInterval is 60
                    for (int i = 0; i < connectionEstablishCount; i++)
                    {
                        try
                        {
                            OpenLoginEnlist(_timeout, connectionOptions, credential, newPassword, newSecurePassword, redirectedUserInstance);
                            break;
                        }
                        catch (SqlException sqlex)
                        {
                            if (i + 1 == connectionEstablishCount 
                                || !applyTransientFaultHandling
                                || _timeout.IsExpired
                                || _timeout.MillisecondsRemaining < transientRetryIntervalInMilliSeconds
                                || !IsTransientError(sqlex))
                            {
                                throw sqlex;
                            }
                            else
                            {
                                Thread.Sleep(transientRetryIntervalInMilliSeconds);
                            }
                        }
                    }
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException) {
                DoomThisConnection();
                throw;
            }
            catch (System.StackOverflowException) {
                DoomThisConnection();
                throw;
            }
            catch (System.Threading.ThreadAbortException) {
                DoomThisConnection();
                throw;
            }
            finally {
                ThreadHasParserLockForClose = false;
                _parserLock.Release();
            }
            if (Bid.AdvancedOn) {
                Bid.Trace("<sc.SqlInternalConnectionTds.ctor|ADV> %d#, constructed new TDS internal connection\n", ObjectID);
            }
        }
 internal void MakePooledConnection(DbConnectionPool connectionPool)
 {
     this._createTime = DateTime.UtcNow;
     this._connectionPool = connectionPool;
     this._performanceCounters = connectionPool.PerformanceCounters;
 }
コード例 #29
0
        override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) {
            SqlConnectionString opt = (SqlConnectionString)options;
            SqlConnectionPoolKey key = (SqlConnectionPoolKey) poolKey;
            SqlInternalConnection result = null;
            SessionData recoverySessionData = null;

            SqlConnectionString userOpt = null;
            if (userOptions != null) {
                userOpt = (SqlConnectionString)userOptions;
            }
            else if (owningConnection != null) {
                userOpt = (SqlConnectionString)(((SqlConnection)owningConnection).UserConnectionOptions);                
            }

            if (owningConnection != null) {
                recoverySessionData = ((SqlConnection)owningConnection)._recoverySessionData;
            }

            if (opt.ContextConnection) {
                result = GetContextConnection(opt, poolGroupProviderInfo);
            }
            else {
                bool redirectedUserInstance       = false;
                DbConnectionPoolIdentity identity = null;

                // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security.
                // Used by notifications.
                if (opt.IntegratedSecurity) {
                    if (pool != null) {
                        identity = pool.Identity;
                    }
                    else {
                        identity = DbConnectionPoolIdentity.GetCurrent();
                    }
                }

                // FOLLOWING IF BLOCK IS ENTIRELY FOR SSE USER INSTANCES
                // If "user instance=true" is in the connection string, we're using SSE user instances
                if (opt.UserInstance) {
                    // opt.DataSource is used to create the SSE connection
                    redirectedUserInstance = true;
                    string instanceName;

                    if ( (null == pool) || 
                         (null != pool && pool.Count <= 0) ) { // Non-pooled or pooled and no connections in the pool.

                        SqlInternalConnectionTds sseConnection = null;
                        try {
                            // What about a failure - throw?  YES!
                            // 



                            SqlConnectionString sseopt = new SqlConnectionString(opt, opt.DataSource, true /* user instance=true */, false /* set Enlist = false */);
                            sseConnection = new SqlInternalConnectionTds(identity, sseopt, key.Credential, null, "", null, false);
                            // NOTE: Retrieve <UserInstanceName> here. This user instance name will be used below to connect to the Sql Express User Instance.
                            instanceName = sseConnection.InstanceName;

                            if (!instanceName.StartsWith("\\\\.\\", StringComparison.Ordinal)) {
                                throw SQL.NonLocalSSEInstance();
                            }

                            if (null != pool) { // Pooled connection - cache result
                                SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo) pool.ProviderInfo;
                                // No lock since we are already in creation mutex
                                providerInfo.InstanceName = instanceName;
                            }
                        }
                        finally {
                            if (null != sseConnection) {
                                sseConnection.Dispose();
                            }
                        }
                    }
                    else { // Cached info from pool.
                        SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo) pool.ProviderInfo;
                        // No lock since we are already in creation mutex
                        instanceName = providerInfo.InstanceName;
                    }

                    // NOTE: Here connection option opt is cloned to set 'instanceName=<UserInstanceName>' that was
                    //       retrieved from the previous SSE connection. For this UserInstance connection 'Enlist=True'.
                    // options immutable - stored in global hash - don't modify
                    opt = new SqlConnectionString(opt, instanceName, false /* user instance=false */, null /* do not modify the Enlist value */);
                    poolGroupProviderInfo = null; // null so we do not pass to constructor below...
                }
                result = new SqlInternalConnectionTds(identity, opt, key.Credential, poolGroupProviderInfo, "", null, redirectedUserInstance, userOpt, recoverySessionData);            
            }
            return result;
        }
 protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
 {
     return new OdbcConnectionOpen(owningObject as OdbcConnection, options as OdbcConnectionString);
 }