/// <summary> /// Creates a new connection to replace an existing connection /// </summary> /// <param name="owningObject">Outer connection that currently owns <paramref name="oldConnection"/></param> /// <param name="userOptions">Options used to create the new connection</param> /// <param name="oldConnection">Inner connection that will be replaced</param> /// <returns>A new inner connection that is attached to the <paramref name="owningObject"/></returns> internal DbConnectionInternal ReplaceConnection(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) { DbConnectionInternal newConnection = UserCreateRequest(owningObject, userOptions, oldConnection); if (newConnection != null) { PrepareConnection(owningObject, newConnection); oldConnection.PrepareForReplaceConnection(); oldConnection.DeactivateConnection(); oldConnection.Dispose(); } return(newConnection); }
private void DeactivateObject(DbConnectionInternal obj) { obj.DeactivateConnection(); bool returnToGeneralPool = false; bool destroyObject = false; if (obj.IsConnectionDoomed) { // the object is not fit for reuse -- just dispose of it. destroyObject = true; } else { // NOTE: constructor should ensure that current state cannot be State.Initializing, so it can only // be State.Running or State.ShuttingDown Debug.Assert(_state == State.Running || _state == State.ShuttingDown); lock (obj) { // A connection with a delegated transaction cannot currently // be returned to a different customer until the transaction // actually completes, so we send it into Stasis -- the SysTx // transaction object will ensure that it is owned (not lost), // and it will be certain to put it back into the pool. if (_state == State.ShuttingDown) { // connection is being closed and the pool has been marked as shutting // down, so destroy this object. destroyObject = true; } else { if (obj.CanBePooled) { // We must put this connection into the transacted pool // while inside a lock to prevent a race condition with // the transaction asyncronously completing on a second // thread. // return to general pool returnToGeneralPool = true; } else { // object is not fit for reuse -- just dispose of it destroyObject = true; } } } } if (returnToGeneralPool) { // Only push the connection into the general pool if we didn't // already push it onto the transacted pool, put it into stasis, // or want to destroy it. Debug.Assert(destroyObject == false); PutNewObject(obj); } else if (destroyObject) { DestroyObject(obj); QueuePoolCreateRequest(); } //------------------------------------------------------------------------------------- // postcondition // ensure that the connection was processed Debug.Assert( returnToGeneralPool == true || destroyObject == true); }