internal void Bind(TdsParserStateObject stateObj) { stateObj.Owner = this; this._stateObj = stateObj; this._parser = stateObj.Parser; this._defaultLCID = this._parser.DefaultLCID; }
public void Close() { // this method will actually close the internal connection and dipose it, this // should only be called by a non-pooled sqlconnection, or by the object pooler // when it deems an object should be destroyed // it's possible to have a connection finalizer, internal connection finalizer, // and the object pool destructor calling this method at the same time, so // we need to provide some synchronization if (_fConnectionOpen) { if (Interlocked.CompareExchange(ref _lock, 1, 0) == 0) { if (_fConnectionOpen) { if (_fIsPooled) { // PerfCounters - on close of pooled connection, decrement count SQL.DecrementPooledConnectionCount(); } try { try { _parser.Disconnect(); // UNDONE: GC.SuppressFinalize causes a permission demand? //GC.SuppressFinalize(_parser); } finally { // _connectionWeakRef= // close will always close, even if exception is thrown // remember to null out any object references _connectionWeakRef = null; _connectionOptions = null; _parser = null; _loginAck = null; _fConnectionOpen = false; // mark internal connection as closed _fUsableState = false; // mark internal connection as unusable _pool = null; _dtcAddress = null; _transactionGuid = Guid.Empty; _transactionExport = null; // always release the lock //Interlocked.CompareExchange(ref _lock, 0, 1); _lock = 0; } } catch { // MDAC 80973 throw; } } else { // release lock in case where connection already closed //Interlocked.CompareExchange(ref _lock, 0, 1); _lock = 0; } } } }
private int _freeStateObjectCount; // Number of available free sessions internal TdsParserSessionPool(TdsParser parser) { _parser = parser; _cache = new List <TdsParserStateObject>(); _freeStateObjects = new TdsParserStateObject[MaxInactiveCount]; _freeStateObjectCount = 0; }
internal SqlCachedBuffer(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj) { int len = 0; this._cachedBytes = new ArrayList(); ulong num = parser.PlpBytesLeft(stateObj); do { if (num == 0L) { return; } do { len = (num > 0x800L) ? 0x800 : ((int)num); byte[] buff = new byte[len]; len = stateObj.ReadPlpBytes(ref buff, 0, len); if (this._cachedBytes.Count == 0) { this.AddByteOrderMark(buff); } this._cachedBytes.Add(buff); num -= len; }while (num > 0L); num = parser.PlpBytesLeft(stateObj); }while (num > 0L); }
internal SqlCachedBuffer(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj) { int len = 0; this._cachedBytes = new ArrayList(); ulong num = parser.PlpBytesLeft(stateObj); do { if (num == 0L) { return; } do { len = (num > 0x800L) ? 0x800 : ((int) num); byte[] buff = new byte[len]; len = stateObj.ReadPlpBytes(ref buff, 0, len); if (this._cachedBytes.Count == 0) { this.AddByteOrderMark(buff); } this._cachedBytes.Add(buff); num -= len; } while (num > 0L); num = parser.PlpBytesLeft(stateObj); } while (num > 0L); }
private int _freeStateObjectCount; // Number of available free sessions internal TdsParserSessionPool(TdsParser parser) { _parser = parser; _cache = new List<TdsParserStateObject>(); _freeStateObjects = new TdsParserStateObject[MaxInactiveCount]; _freeStateObjectCount = 0; }
private void OpenAndLogin() { // Open the connection and Login try { int timeout = _connectionOptions.ConnectTimeout; _parser = new TdsParser(); timeout = _parser.Connect(_connectionOptions.DataSource, _connectionOptions.NetworkLibrary, this, timeout, _connectionOptions.Encrypt); this.Login(timeout); _fConnectionOpen = true; // mark connection as open } catch (Exception e) { ADP.TraceException(e); // If the parser was allocated and we failed, then we must have failed on // either the Connect or Login, either way we should call Disconnect. // Disconnect can be called if the connection is already closed - becomes // no-op, so no issues there. if (_parser != null) { _parser.Disconnect(); } throw e; } }
static internal void BestEffortCleanup(TdsParser target) { if (null != target) { target.BestEffortCleanup(); } }
//////////////////////////////////////////////////////////////////////////////////////// // 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); } }
internal override void DisconnectTransaction(SqlInternalTransaction internalTransaction) { TdsParser parser = this.Parser; if (parser != null) { parser.DisconnectTransaction(internalTransaction); } }
private int _freeStateObjectCount; // Number of available free sessions internal TdsParserSessionPool(TdsParser parser) { _parser = parser; _cache = new List<TdsParserStateObject>(); _freeStateObjects = new TdsParserStateObject[MaxInactiveCount]; _freeStateObjectCount = 0; if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.ctor|ADV> %d# created session pool for parser %d\n", ObjectID, parser.ObjectID); } }
internal TdsParserSessionPool(TdsParser parser) { this._parser = parser; this._cache = new List<TdsParserStateObject>(); this._freeStack = new TdsParserStateObjectListStack(); if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.ctor|ADV> %d# created session pool for parser %d\n", this.ObjectID, parser.ObjectID); } }
internal TdsParserSessionPool(TdsParser parser) { this._parser = parser; this._cache = new List <TdsParserStateObject>(); this._freeStack = new TdsParserStateObjectListStack(); if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.ctor|ADV> %d# created session pool for parser %d\n", this.ObjectID, parser.ObjectID); } }
internal TdsParserStateObject CreateSessionObject(TdsParser tdsParser, TdsParserStateObject _pMarsPhysicalConObj, bool v) { if (TdsParserStateObjectFactory.UseManagedSNI) { return(new TdsParserStateObjectManaged(tdsParser, _pMarsPhysicalConObj, true)); } else { return(new TdsParserStateObjectNative(tdsParser, _pMarsPhysicalConObj, true)); } }
public TdsParserStateObject CreateTdsParserStateObject(TdsParser parser) { if (UseManagedSNI) { return(new TdsParserStateObjectManaged(parser)); } else { return(new TdsParserStateObjectNative(parser)); } }
private int _freeStateObjectCount; // Number of available free sessions internal TdsParserSessionPool(TdsParser parser) { _parser = parser; _cache = new List <TdsParserStateObject>(); _freeStateObjects = new TdsParserStateObject[MaxInactiveCount]; _freeStateObjectCount = 0; if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParserSessionPool.ctor|ADV> %d# created session pool for parser %d\n", ObjectID, parser.ObjectID); } }
static public void DeriveParameters(SqlCommand command) // MDAC 65927\ { SqlConnection.ExecutePermission.Demand(); if (null == command) { throw ADP.ArgumentNull("command"); } TdsParser bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(command.Connection); command.DeriveParameters(); } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif } catch (System.OutOfMemoryException e) { if (null != command && null != command.Connection) { command.Connection.Abort(e); } throw; } catch (System.StackOverflowException e) { if (null != command && null != command.Connection) { command.Connection.Abort(e); } throw; } catch (System.Threading.ThreadAbortException e) { if (null != command && null != command.Connection) { command.Connection.Abort(e); } SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } }
internal TdsParserStateObject(TdsParser parser) { this._objectID = Interlocked.Increment(ref _objectTypeCount); this._owner = new WeakReference(null); this._inputHeaderLen = 8; this._outputHeaderLen = 8; this._outBytesUsed = 8; this._outputPacketNumber = 1; this._bTmp = new byte[12]; this._parser = parser; this.SetPacketSize(0x1000); this.IncrementPendingCallbacks(); }
// Reads off from the network buffer and caches bytes. Only reads one column value in the current row. internal static bool TryCreate(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj, out SqlCachedBuffer buffer) { int cb = 0; ulong plplength; byte[] byteArr; List <byte[]> cachedBytes = new List <byte[]>(); buffer = null; // the very first length is already read. if (!parser.TryPlpBytesLeft(stateObj, out plplength)) { return(false); } // For now we only handle Plp data from the parser directly. Debug.Assert(metadata.metaType.IsPlp, "SqlCachedBuffer call on a non-plp data"); do { if (plplength == 0) { break; } do { cb = (plplength > (ulong)_maxChunkSize) ? _maxChunkSize : (int)plplength; byteArr = new byte[cb]; if (!stateObj.TryReadPlpBytes(ref byteArr, 0, cb, out cb)) { return(false); } Debug.Assert(cb == byteArr.Length); if (cachedBytes.Count == 0) { // Add the Byte order mark if needed if we read the first array AddByteOrderMark(byteArr, cachedBytes); } cachedBytes.Add(byteArr); plplength -= (ulong)cb; } while (plplength > 0); if (!parser.TryPlpBytesLeft(stateObj, out plplength)) { return(false); } } while (plplength > 0); Debug.Assert(stateObj._longlen == 0 && stateObj._longlenleft == 0); buffer = new SqlCachedBuffer(cachedBytes); return(true); }
internal static SNIHandle GetBestEffortCleanupTarget(SqlConnection connection) { if (connection != null) { SqlInternalConnectionTds innerConnection = connection.InnerConnection as SqlInternalConnectionTds; if (innerConnection != null) { TdsParser parser = innerConnection.Parser; if (parser != null) { return(parser.GetBestEffortCleanupTarget()); } } } return(null); }
// Reads off from the network buffer and caches bytes. Only reads one column value in the current row. static internal bool TryCreate(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj, out SqlCachedBuffer buffer) { int cb = 0; ulong plplength; byte[] byteArr; List<byte[]> cachedBytes = new List<byte[]>(); buffer = null; // the very first length is already read. if (!parser.TryPlpBytesLeft(stateObj, out plplength)) { return false; } // For now we only handle Plp data from the parser directly. Debug.Assert(metadata.metaType.IsPlp, "SqlCachedBuffer call on a non-plp data"); do { if (plplength == 0) break; do { cb = (plplength > (ulong)_maxChunkSize) ? _maxChunkSize : (int)plplength; byteArr = new byte[cb]; if (!stateObj.TryReadPlpBytes(ref byteArr, 0, cb, out cb)) { return false; } Debug.Assert(cb == byteArr.Length); if (cachedBytes.Count == 0) { // Add the Byte order mark if needed if we read the first array AddByteOrderMark(byteArr, cachedBytes); } cachedBytes.Add(byteArr); plplength -= (ulong)cb; } while (plplength > 0); if (!parser.TryPlpBytesLeft(stateObj, out plplength)) { return false; } } while (plplength > 0); Debug.Assert(stateObj._longlen == 0 && stateObj._longlenleft == 0); buffer = new SqlCachedBuffer(cachedBytes); return true; }
protected override void Dispose(bool disposing) { if (disposing) { 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); if (!IsZombied && !IsYukonPartialZombie) { _internalTransaction.Dispose(); } } #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; } } base.Dispose(disposing); }
public override void Dispose() { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.Dispose|ADV> %d# disposing\n", base.ObjectID); } try { TdsParser parser = Interlocked.Exchange <TdsParser>(ref this._parser, null); if (parser != null) { parser.Disconnect(); } } finally { this._loginAck = null; this._fConnectionOpen = false; } base.Dispose(); }
internal TdsParserStateObject(TdsParser parser, SNIHandle physicalConnection, bool async) { this._objectID = Interlocked.Increment(ref _objectTypeCount); this._owner = new WeakReference(null); this._inputHeaderLen = 8; this._outputHeaderLen = 8; this._outBytesUsed = 8; this._outputPacketNumber = 1; this._bTmp = new byte[12]; this._parser = parser; this.SniContext = System.Data.SqlClient.SniContext.Snix_GetMarsSession; this.SetPacketSize(this._parser._physicalStateObj._outBuff.Length); SNINativeMethodWrapper.ConsumerInfo myInfo = this.CreateConsumerInfo(async); this._sessionHandle = new SNIHandle(myInfo, "session:", physicalConnection); if (this._sessionHandle.Status != 0) { parser.Errors.Add(parser.ProcessSNIError(this)); parser.ThrowExceptionAndWarning(); } this.IncrementPendingCallbacks(); }
private void Dispose(bool disposing) { if (disposing) { this._columnMappings = null; this._parser = null; try { if (this._internalTransaction != null) { this._internalTransaction.Rollback(); this._internalTransaction.Dispose(); this._internalTransaction = null; } } catch (Exception exception) { if (!ADP.IsCatchableExceptionType(exception)) { throw; } ADP.TraceExceptionWithoutRethrow(exception); } finally { if (this._connection != null) { if (this._ownConnection) { this._connection.Dispose(); } this._connection = null; } } } }
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); } } }
internal void ExecuteTransactionYukon(SqlInternalConnection.TransactionRequest transactionRequest, string transactionName, System.Data.IsolationLevel iso, SqlInternalTransaction internalTransaction, bool isDelegateControlRequest) { TdsEnums.TransactionManagerRequestType begin = TdsEnums.TransactionManagerRequestType.Begin; TdsEnums.TransactionManagerIsolationLevel readCommitted = TdsEnums.TransactionManagerIsolationLevel.ReadCommitted; switch (iso) { case System.Data.IsolationLevel.Unspecified: readCommitted = TdsEnums.TransactionManagerIsolationLevel.Unspecified; break; case System.Data.IsolationLevel.Chaos: throw SQL.NotSupportedIsolationLevel(iso); case System.Data.IsolationLevel.ReadUncommitted: readCommitted = TdsEnums.TransactionManagerIsolationLevel.ReadUncommitted; break; case System.Data.IsolationLevel.Serializable: readCommitted = TdsEnums.TransactionManagerIsolationLevel.Serializable; break; case System.Data.IsolationLevel.Snapshot: readCommitted = TdsEnums.TransactionManagerIsolationLevel.Snapshot; break; case System.Data.IsolationLevel.ReadCommitted: readCommitted = TdsEnums.TransactionManagerIsolationLevel.ReadCommitted; break; case System.Data.IsolationLevel.RepeatableRead: readCommitted = TdsEnums.TransactionManagerIsolationLevel.RepeatableRead; break; default: throw ADP.InvalidIsolationLevel(iso); } TdsParserStateObject session = this._parser._physicalStateObj; TdsParser parser = this._parser; bool flag = false; bool lockTaken = false; try { switch (transactionRequest) { case SqlInternalConnection.TransactionRequest.Begin: begin = TdsEnums.TransactionManagerRequestType.Begin; break; case SqlInternalConnection.TransactionRequest.Promote: begin = TdsEnums.TransactionManagerRequestType.Promote; break; case SqlInternalConnection.TransactionRequest.Commit: begin = TdsEnums.TransactionManagerRequestType.Commit; break; case SqlInternalConnection.TransactionRequest.Rollback: case SqlInternalConnection.TransactionRequest.IfRollback: begin = TdsEnums.TransactionManagerRequestType.Rollback; break; case SqlInternalConnection.TransactionRequest.Save: begin = TdsEnums.TransactionManagerRequestType.Save; break; } if ((internalTransaction != null) && internalTransaction.IsDelegated) { if (!this._parser.MARSOn) { if (internalTransaction.OpenResultsCount != 0) { throw SQL.CannotCompleteDelegatedTransactionWithOpenResults(); } Monitor.Enter(session, ref lockTaken); if (internalTransaction.OpenResultsCount != 0) { throw SQL.CannotCompleteDelegatedTransactionWithOpenResults(); } } else { session = this._parser.GetSession(this); flag = true; } } this._parser.TdsExecuteTransactionManagerRequest(null, begin, transactionName, readCommitted, base.ConnectionOptions.ConnectTimeout, internalTransaction, session, isDelegateControlRequest); } finally { if (flag) { parser.PutSession(session); } if (lockTaken) { Monitor.Exit(session); } } }
private readonly Dictionary <IntPtr, SNIPacket> _pendingWritePackets = new Dictionary <IntPtr, SNIPacket>(); // Stores write packets that have been sent to SNI, but have not yet finished writing (i.e. we are waiting for SNI's callback) internal TdsParserStateObjectNative(TdsParser parser, TdsParserStateObject physicalConnection, bool async) : base(parser, physicalConnection, async) { }
public TdsOutputStream(TdsParser parser, TdsParserStateObject stateObj, byte[] preambleToStrip) { _parser = parser; _stateObj = stateObj; _preambleToStrip = preambleToStrip; }
internal TdsParserStateObject CreateSessionObject(TdsParser tdsParser, TdsParserStateObject _pMarsPhysicalConObj, bool v) { return(new TdsParserStateObjectManaged(tdsParser, _pMarsPhysicalConObj, true)); }
#pragma warning restore 0649 #endif ////////////////// // Constructors // ////////////////// internal TdsParserStateObject(TdsParser parser) { // Construct a physical connection Debug.Assert(null != parser, "no parser?"); _parser = parser; // For physical connection, initialize to default login packet size. SetPacketSize(TdsEnums.DEFAULT_LOGIN_PACKET_SIZE); // we post a callback that represents the call to dispose; once the // object is disposed, the next callback will cause the GC Handle to // be released. IncrementPendingCallbacks(); _lastSuccessfulIOTimer = new LastIOTimer(); }
// Attempt to login to a host that does not have a failover partner // // Will repeatedly attempt to connect, but back off between each attempt so as not to clog the network. // Back off period increases for first few failures: 100ms, 200ms, 400ms, 800ms, then 1000ms for subsequent attempts // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // DEVNOTE: The logic in this method is paralleled by the logic in LoginWithFailover. // Changes to either one should be examined to see if they need to be reflected in the other // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureString newSecurePassword, bool redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) { Debug.Assert(object.ReferenceEquals(connectionOptions, this.ConnectionOptions), "ConnectionOptions argument and property must be the same"); // consider removing the argument int routingAttempts = 0; ServerInfo originalServerInfo = serverInfo; // serverInfo may end up pointing to new object due to routing, original object is used to set CurrentDatasource if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, host=%ls\n", ObjectID, serverInfo.UserServerName); } int sleepInterval = 100; //milliseconds to sleep (back off) between attempts. ResolveExtendedServerName(serverInfo, !redirectedUserInstance, connectionOptions); long timeoutUnitInterval = 0; Boolean isParallel = connectionOptions.MultiSubnetFailover || connectionOptions.TransparentNetworkIPResolution; if(isParallel) { // Determine unit interval if (timeout.IsInfinite) { timeoutUnitInterval = checked((long)(ADP.FailoverTimeoutStep * (1000L * ADP.DefaultConnectionTimeout))); } else { timeoutUnitInterval = checked((long)(ADP.FailoverTimeoutStep * timeout.MillisecondsRemaining)); } } // Only three ways out of this loop: // 1) Successfully connected // 2) Parser threw exception while main timer was expired // 3) Parser threw logon failure-related exception // 4) Parser threw exception in post-initial connect code, // such as pre-login handshake or during actual logon. (parser state != Closed) // // Of these methods, only #1 exits normally. This preserves the call stack on the exception // back into the parser for the error cases. int attemptNumber = 0; TimeoutTimer intervalTimer = null; TimeoutTimer firstTransparentAttemptTimeout = TimeoutTimer.StartMillisecondsTimeout(ADP.FirstTransparentAttemptTimeout); TimeoutTimer attemptOneLoginTimeout = timeout; while(true) { if(isParallel) { attemptNumber++; // Set timeout for this attempt, but don't exceed original timer long nextTimeoutInterval = checked(timeoutUnitInterval * attemptNumber); long milliseconds = timeout.MillisecondsRemaining; if (nextTimeoutInterval > milliseconds) { nextTimeoutInterval = milliseconds; } intervalTimer = TimeoutTimer.StartMillisecondsTimeout(nextTimeoutInterval); } // Re-allocate parser each time to make sure state is known // RFC 50002652 - if parser was created by previous attempt, dispose it to properly close the socket, if created if (_parser != null) _parser.Disconnect(); _parser = new TdsParser(ConnectionOptions.MARS, ConnectionOptions.Asynchronous); Debug.Assert(SniContext.Undefined== Parser._physicalStateObj.SniContext, String.Format((IFormatProvider)null, "SniContext should be Undefined; actual Value: {0}", Parser._physicalStateObj.SniContext)); try { // Boolean isFirstTransparentAttempt = connectionOptions.TransparentNetworkIPResolution && attemptNumber == 1; if(isFirstTransparentAttempt) { attemptOneLoginTimeout = firstTransparentAttemptTimeout; } else { if(isParallel) { attemptOneLoginTimeout = intervalTimer; } } AttemptOneLogin( serverInfo, newPassword, newSecurePassword, !isParallel, // ignore timeout for SniOpen call unless MSF , and TNIR attemptOneLoginTimeout, isFirstTransparentAttempt:isFirstTransparentAttempt); if (connectionOptions.MultiSubnetFailover && null != ServerProvidedFailOverPartner) { // connection succeeded: trigger exception if server sends failover partner and MultiSubnetFailover is used. throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: true, internalConnection: this); } if (_routingInfo != null) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover> Routed to %ls", serverInfo.ExtendedServerName); if (routingAttempts > 0) { throw SQL.ROR_RecursiveRoutingNotSupported(this); } if (timeout.IsExpired) { throw SQL.ROR_TimeoutAfterRoutingInfo(this); } serverInfo = new ServerInfo(ConnectionOptions, _routingInfo, serverInfo.ResolvedServerName); timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.RoutingDestination); _originalClientConnectionId = _clientConnectionId; _routingDestination = serverInfo.UserServerName; // restore properties that could be changed by the environment tokens _currentPacketSize = ConnectionOptions.PacketSize; _currentLanguage = _originalLanguage = ConnectionOptions.CurrentLanguage; CurrentDatabase = _originalDatabase = ConnectionOptions.InitialCatalog; _currentFailoverPartner = null; _instanceName = String.Empty; routingAttempts++; continue; // repeat the loop, but skip code reserved for failed connections (after the catch) } else { break; // leave the while loop -- we've successfully connected } } catch (SqlException sqlex) { if (null == _parser || TdsParserState.Closed != _parser.State || IsDoNotRetryConnectError(sqlex) || timeout.IsExpired) { // no more time to try again throw; // Caller will call LoginFailure() } // Check sleep interval to make sure we won't exceed the timeout // Do this in the catch block so we can re-throw the current exception if (timeout.MillisecondsRemaining <= sleepInterval) { throw; } // } // We only get here when we failed to connect, but are going to re-try // Switch to failover logic if the server provided a partner if (null != ServerProvidedFailOverPartner) { if (connectionOptions.MultiSubnetFailover) { // connection failed: do not allow failover to server-provided failover partner if MultiSubnetFailover is set throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: true, internalConnection: this); } Debug.Assert(ConnectionOptions.ApplicationIntent != ApplicationIntent.ReadOnly, "FAILOVER+AppIntent=RO: Should already fail (at LOGSHIPNODE in OnEnvChange)"); timeoutErrorInternal.ResetAndRestartPhase(); timeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.PreLoginBegin); timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Failover); timeoutErrorInternal.SetFailoverScenario(true); // this is a failover scenario LoginWithFailover( true, // start by using failover partner, since we already failed to connect to the primary serverInfo, ServerProvidedFailOverPartner, newPassword, newSecurePassword, redirectedUserInstance, connectionOptions, credential, timeout); return; // LoginWithFailover successfully connected and handled entire connection setup } // Sleep for a bit to prevent clogging the network with requests, // then update sleep interval for next iteration (max 1 second interval) if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, sleeping %d{milisec}\n", ObjectID, sleepInterval); } Thread.Sleep(sleepInterval); sleepInterval = (sleepInterval < 500) ? sleepInterval * 2 : 1000; } if (null != PoolGroupProviderInfo) { // We must wait for CompleteLogin to finish for to have the // env change from the server to know its designated failover // partner; save this information in _currentFailoverPartner. PoolGroupProviderInfo.FailoverCheck(this, false, connectionOptions, ServerProvidedFailOverPartner); } CurrentDataSource = originalServerInfo.UserServerName; }
override protected void Deactivate() { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnection.Deactivate|ADV> %d# deactivating\n", base.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); SqlReferenceCollection referenceCollection = (SqlReferenceCollection)ReferenceCollection; if (null != referenceCollection) { referenceCollection.Deactivate(); } // Invoke subclass-specific deactivation logic InternalDeactivate(); } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException) { DoomThisConnection(); throw; } catch (System.StackOverflowException) { DoomThisConnection(); throw; } catch (System.Threading.ThreadAbortException) { DoomThisConnection(); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } catch (Exception e) { // if (!ADP.IsCatchableExceptionType(e)) { throw; } // if an exception occurred, the inner connection will be // marked as unusable and destroyed upon returning to the // pool DoomThisConnection(); ADP.TraceExceptionWithoutRethrow(e); } }
private void EnlistNonNull(SysTx.Transaction tx) { Debug.Assert(null != tx, "null transaction?"); if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, transaction %d#.\n", base.ObjectID, tx.GetHashCode()); } bool hasDelegatedTransaction = false; if (IsYukonOrNewer) { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, attempting to delegate\n", base.ObjectID); } // Promotable transactions are only supported on Yukon // servers or newer. SqlDelegatedTransaction delegatedTransaction = new SqlDelegatedTransaction(this, tx); try { // NOTE: System.Transactions claims to resolve all // potential race conditions between multiple delegate // requests of the same transaction to different // connections in their code, such that only one // attempt to delegate will succeed. // NOTE: PromotableSinglePhaseEnlist will eventually // make a round trip to the server; doing this inside // a lock is not the best choice. We presume that you // aren't trying to enlist concurrently on two threads // and leave it at that -- We don't claim any thread // safety with regard to multiple concurrent requests // to enlist the same connection in different // transactions, which is good, because we don't have // it anyway. // PromotableSinglePhaseEnlist may not actually promote // the transaction when it is already delegated (this is // the way they resolve the race condition when two // threads attempt to delegate the same Lightweight // Transaction) In that case, we can safely ignore // our delegated transaction, and proceed to enlist // in the promoted one. if (tx.EnlistPromotableSinglePhase(delegatedTransaction)) { hasDelegatedTransaction = true; this.DelegatedTransaction = delegatedTransaction; if (Bid.AdvancedOn) { long transactionId = SqlInternalTransaction.NullTransactionId; int transactionObjectID = 0; if (null != CurrentTransaction) { transactionId = CurrentTransaction.TransactionId; transactionObjectID = CurrentTransaction.ObjectID; } Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, delegated to transaction %d# with transactionId=0x%I64x\n", base.ObjectID, transactionObjectID, transactionId); } } } catch (SqlException e) { // we do not want to eat the error if it is a fatal one if (e.Class >= TdsEnums.FATAL_ERROR_CLASS) { throw; } // if the parser is null or its state is not openloggedin, the connection is no longer good. SqlInternalConnectionTds tdsConnection = this as SqlInternalConnectionTds; if (tdsConnection != null) { TdsParser parser = tdsConnection.Parser; if (parser == null || parser.State != TdsParserState.OpenLoggedIn) { throw; } } ADP.TraceExceptionWithoutRethrow(e); // In this case, SqlDelegatedTransaction.Initialize // failed and we don't necessarily want to reject // things -- there may have been a legitimate reason // for the failure. } } if (!hasDelegatedTransaction) { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, delegation not possible, enlisting.\n", base.ObjectID); } byte[] cookie = null; if (null == _whereAbouts) { byte[] dtcAddress = GetDTCAddress(); if (null == dtcAddress) { throw SQL.CannotGetDTCAddress(); } _whereAbouts = dtcAddress; } cookie = GetTransactionCookie(tx, _whereAbouts); // send cookie to server to finish enlistment PropagateTransactionCookie(cookie); _isEnlistedInTransaction = true; if (Bid.AdvancedOn) { long transactionId = SqlInternalTransaction.NullTransactionId; int transactionObjectID = 0; if (null != CurrentTransaction) { transactionId = CurrentTransaction.TransactionId; transactionObjectID = CurrentTransaction.ObjectID; } Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, enlisted with transaction %d# with transactionId=0x%I64x\n", base.ObjectID, transactionObjectID, transactionId); } } EnlistedTransaction = tx; // Tell the base class about our enlistment // If we're on a Yukon or newer server, and we we delegate the // transaction successfully, we will have done a begin transaction, // which produces a transaction id that we should execute all requests // on. The TdsParser or SmiEventSink will store this information as // the current transaction. // // Likewise, propagating a transaction to a Yukon or newer server will // produce a transaction id that The TdsParser or SmiEventSink will // store as the current transaction. // // In either case, when we're working with a Yukon or newer server // we better have a current transaction by now. Debug.Assert(!IsYukonOrNewer || null != CurrentTransaction, "delegated/enlisted transaction with null current transaction?"); }
private void CloseInternal(bool closeReader) { TdsParser parser = this._parser; TdsParserStateObject stateObj = this._stateObj; bool flag2 = this.IsCommandBehavior(CommandBehavior.CloseConnection); this._parser = null; bool flag = false; RuntimeHelpers.PrepareConstrainedRegions(); try { if (((parser != null) && (stateObj != null)) && (stateObj._pendingData && (parser.State == TdsParserState.OpenLoggedIn))) { if (this._altRowStatus == ALTROWSTATUS.AltRow) { this._dataReady = true; } if (this._dataReady) { this.CleanPartialRead(); } parser.Run(RunBehavior.Clean, this._command, this, null, stateObj); } this.RestoreServerSettings(parser, stateObj); } catch (OutOfMemoryException exception6) { this._isClosed = true; flag = true; if (this._connection != null) { this._connection.Abort(exception6); } throw; } catch (StackOverflowException exception5) { this._isClosed = true; flag = true; if (this._connection != null) { this._connection.Abort(exception5); } throw; } catch (ThreadAbortException exception4) { this._isClosed = true; flag = true; if (this._connection != null) { this._connection.Abort(exception4); } throw; } finally { if (flag) { this._isClosed = true; this._command = null; this._connection = null; this._statistics = null; } else if (closeReader) { this._stateObj = null; this._data = null; if (this.Connection != null) { this.Connection.RemoveWeakReference(this); } RuntimeHelpers.PrepareConstrainedRegions(); try { if ((this._command != null) && (stateObj != null)) { stateObj.CloseSession(); } } catch (OutOfMemoryException exception3) { this._isClosed = true; flag = true; if (this._connection != null) { this._connection.Abort(exception3); } throw; } catch (StackOverflowException exception2) { this._isClosed = true; flag = true; if (this._connection != null) { this._connection.Abort(exception2); } throw; } catch (ThreadAbortException exception) { this._isClosed = true; flag = true; if (this._connection != null) { this._connection.Abort(exception); } throw; } this.SetMetaData(null, false); this._dataReady = false; this._isClosed = true; this._fieldNameLookup = null; if (flag2 && (this.Connection != null)) { this.Connection.Close(); } if (this._command != null) { this._recordsAffected = this._command.InternalRecordsAffected; } this._command = null; this._connection = null; this._statistics = null; } } }
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); } }
private void LoginWithFailover(bool useFailoverHost, ServerInfo primaryServerInfo, string failoverHost, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout) { long num5; if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, useFailover=%d{bool}, primary=", base.ObjectID, useFailoverHost); Bid.PutStr(primaryServerInfo.UserServerName); Bid.PutStr(", failover="); Bid.PutStr(failoverHost); Bid.PutStr("\n"); } int num = 100; string networkLibrary = base.ConnectionOptions.NetworkLibrary; ServerInfo serverInfo = new ServerInfo(connectionOptions, failoverHost); this.ResolveExtendedServerName(primaryServerInfo, !redirectedUserInstance, owningObject); if (this.ServerProvidedFailOverPartner == null) { this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance && (failoverHost != primaryServerInfo.UserServerName), owningObject); } if (timeout.IsInfinite) { ADP.TimerFromSeconds(15); num5 = 0L; } else { num5 = (long)(0.08f * timeout.MillisecondsRemaining); } bool flag = false; int num2 = 0; while (true) { ServerInfo info2; long milliseconds = num5 * ((num2 / 2) + 1); long millisecondsRemaining = timeout.MillisecondsRemaining; if (milliseconds > millisecondsRemaining) { milliseconds = millisecondsRemaining; } TimeoutTimer timer = TimeoutTimer.StartMillisecondsTimeout(milliseconds); if (this._parser != null) { this._parser.Disconnect(); } this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous); if (useFailoverHost) { if (!flag) { this.FailoverPermissionDemand(); flag = true; } if ((this.ServerProvidedFailOverPartner != null) && (serverInfo.ResolvedServerName != this.ServerProvidedFailOverPartner)) { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, new failover partner=%ls\n", base.ObjectID, this.ServerProvidedFailOverPartner); } serverInfo.SetDerivedNames(networkLibrary, this.ServerProvidedFailOverPartner); } info2 = serverInfo; } else { info2 = primaryServerInfo; } try { this.AttemptOneLogin(info2, newPassword, false, timer, owningObject); if (this._routingInfo != null) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover> Routed to %ls", this._routingInfo.ServerName); throw SQL.ROR_UnexpectedRoutingInfo(); } break; } catch (SqlException exception) { if (this.IsDoNotRetryConnectError(exception) || timeout.IsExpired) { throw; } if (base.IsConnectionDoomed) { throw; } if ((1 == (num2 % 2)) && (timeout.MillisecondsRemaining <= num)) { throw; } } if (1 == (num2 % 2)) { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, sleeping %d{milisec}\n", base.ObjectID, num); } Thread.Sleep(num); num = (num < 500) ? (num * 2) : 0x3e8; } num2++; useFailoverHost = !useFailoverHost; } if (useFailoverHost && (this.ServerProvidedFailOverPartner == null)) { throw SQL.InvalidPartnerConfiguration(failoverHost, base.CurrentDatabase); } if (this.PoolGroupProviderInfo != null) { this.PoolGroupProviderInfo.FailoverCheck(this, useFailoverHost, connectionOptions, this.ServerProvidedFailOverPartner); } base.CurrentDataSource = useFailoverHost ? failoverHost : primaryServerInfo.UserServerName; }
private void LoginNoFailover(ServerInfo serverInfo, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout) { int num2 = 0; ServerInfo info = serverInfo; if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, host=%ls\n", base.ObjectID, serverInfo.UserServerName); } int num = 100; this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance, owningObject); Label_0032: if (this._parser != null) { this._parser.Disconnect(); } this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous); try { this.AttemptOneLogin(serverInfo, newPassword, true, timeout, owningObject); if (connectionOptions.MultiSubnetFailover && (this.ServerProvidedFailOverPartner != null)) { bool serverProvidedFailoverPartner = true; throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner); } if (this._routingInfo == null) { if (this.PoolGroupProviderInfo != null) { this.PoolGroupProviderInfo.FailoverCheck(this, false, connectionOptions, this.ServerProvidedFailOverPartner); } base.CurrentDataSource = info.UserServerName; return; } Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover> Routed to %ls", serverInfo.ExtendedServerName); if (num2 > 0) { throw SQL.ROR_RecursiveRoutingNotSupported(); } if (timeout.IsExpired) { throw SQL.ROR_TimeoutAfterRoutingInfo(); } serverInfo = new ServerInfo(base.ConnectionOptions, this._routingInfo, serverInfo.ResolvedServerName); this._currentPacketSize = base.ConnectionOptions.PacketSize; this._currentLanguage = this._originalLanguage = base.ConnectionOptions.CurrentLanguage; base.CurrentDatabase = this._originalDatabase = base.ConnectionOptions.InitialCatalog; this._currentFailoverPartner = null; this._instanceName = string.Empty; num2++; goto Label_0032; } catch (SqlException exception) { if (((this._parser == null) || (this._parser.State != TdsParserState.Closed)) || (this.IsDoNotRetryConnectError(exception) || timeout.IsExpired)) { throw; } if (timeout.MillisecondsRemaining <= num) { throw; } } if (this.ServerProvidedFailOverPartner != null) { if (connectionOptions.MultiSubnetFailover) { bool flag = true; throw SQL.MultiSubnetFailoverWithFailoverPartner(flag); } this.LoginWithFailover(true, serverInfo, this.ServerProvidedFailOverPartner, newPassword, redirectedUserInstance, owningObject, connectionOptions, timeout); } else { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, sleeping %d{milisec}\n", base.ObjectID, num); } Thread.Sleep(num); num = (num < 500) ? (num * 2) : 0x3e8; goto Label_0032; } }
private void LoginWithFailover(bool useFailoverHost, ServerInfo primaryServerInfo, string failoverHost, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout) { long num5; if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, useFailover=%d{bool}, primary=", base.ObjectID, useFailoverHost); Bid.PutStr(primaryServerInfo.UserServerName); Bid.PutStr(", failover="); Bid.PutStr(failoverHost); Bid.PutStr("\n"); } int num = 100; string networkLibrary = base.ConnectionOptions.NetworkLibrary; ServerInfo serverInfo = new ServerInfo(connectionOptions, failoverHost); this.ResolveExtendedServerName(primaryServerInfo, !redirectedUserInstance, owningObject); if (this.ServerProvidedFailOverPartner == null) { this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance && (failoverHost != primaryServerInfo.UserServerName), owningObject); } if (timeout.IsInfinite) { ADP.TimerFromSeconds(15); num5 = 0L; } else { num5 = (long) (0.08f * timeout.MillisecondsRemaining); } bool flag = false; int num2 = 0; while (true) { ServerInfo info2; long milliseconds = num5 * ((num2 / 2) + 1); long millisecondsRemaining = timeout.MillisecondsRemaining; if (milliseconds > millisecondsRemaining) { milliseconds = millisecondsRemaining; } TimeoutTimer timer = TimeoutTimer.StartMillisecondsTimeout(milliseconds); if (this._parser != null) { this._parser.Disconnect(); } this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous); if (useFailoverHost) { if (!flag) { this.FailoverPermissionDemand(); flag = true; } if ((this.ServerProvidedFailOverPartner != null) && (serverInfo.ResolvedServerName != this.ServerProvidedFailOverPartner)) { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, new failover partner=%ls\n", base.ObjectID, this.ServerProvidedFailOverPartner); } serverInfo.SetDerivedNames(networkLibrary, this.ServerProvidedFailOverPartner); } info2 = serverInfo; } else { info2 = primaryServerInfo; } try { this.AttemptOneLogin(info2, newPassword, false, timer, owningObject); if (this._routingInfo != null) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover> Routed to %ls", this._routingInfo.ServerName); throw SQL.ROR_UnexpectedRoutingInfo(); } break; } catch (SqlException exception) { if (this.IsDoNotRetryConnectError(exception) || timeout.IsExpired) { throw; } if (base.IsConnectionDoomed) { throw; } if ((1 == (num2 % 2)) && (timeout.MillisecondsRemaining <= num)) { throw; } } if (1 == (num2 % 2)) { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, sleeping %d{milisec}\n", base.ObjectID, num); } Thread.Sleep(num); num = (num < 500) ? (num * 2) : 0x3e8; } num2++; useFailoverHost = !useFailoverHost; } if (useFailoverHost && (this.ServerProvidedFailOverPartner == null)) { throw SQL.InvalidPartnerConfiguration(failoverHost, base.CurrentDatabase); } if (this.PoolGroupProviderInfo != null) { this.PoolGroupProviderInfo.FailoverCheck(this, useFailoverHost, connectionOptions, this.ServerProvidedFailOverPartner); } base.CurrentDataSource = useFailoverHost ? failoverHost : primaryServerInfo.UserServerName; }
override public void EnlistTransaction(SysTx.Transaction transaction) { SqlConnection.VerifyExecutePermission(); ValidateConnectionForExecute(null); // If a connection has a local transaction outstanding and you try // to enlist in a DTC transaction, SQL Server will rollback the // local transaction and then do the enlist (7.0 and 2000). So, if // the user tries to do this, throw. if (HasLocalTransaction) { throw ADP.LocalTransactionPresent(); } if (null != transaction && transaction.Equals(EnlistedTransaction)) { // No-op if this is the current transaction return; } // If a connection is already enlisted in a DTC transaction and you // try to enlist in another one, in 7.0 the existing DTC transaction // would roll back and then the connection would enlist in the new // one. In SQL 2000 & Yukon, when you enlist in a DTC transaction // while the connection is already enlisted in a DTC transaction, // the connection simply switches enlistments. Regardless, simply // enlist in the user specified distributed transaction. This // behavior matches OLEDB and ODBC. 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); Enlist(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; } }
private void RestoreServerSettings(TdsParser parser, TdsParserStateObject stateObj) { if ((parser != null) && (this._resetOptionsString != null)) { if (parser.State == TdsParserState.OpenLoggedIn) { parser.TdsExecuteSQLBatch(this._resetOptionsString, (this._command != null) ? this._command.CommandTimeout : 0, null, stateObj); parser.Run(RunBehavior.UntilDone, this._command, this, null, stateObj); } this._resetOptionsString = null; } }
internal TdsParserStateObject(TdsParser parser, SNIHandle physicalConnection, bool async) { // Construct a MARS session Debug.Assert(null != parser, "no parser?"); _parser = parser; SniContext = SniContext.Snix_GetMarsSession; Debug.Assert(null != _parser._physicalStateObj, "no physical session?"); Debug.Assert(null != _parser._physicalStateObj._inBuff, "no in buffer?"); Debug.Assert(null != _parser._physicalStateObj._outBuff, "no out buffer?"); Debug.Assert(_parser._physicalStateObj._outBuff.Length == _parser._physicalStateObj._inBuff.Length, "Unexpected unequal buffers."); // Determine packet size based on physical connection buffer lengths. SetPacketSize(_parser._physicalStateObj._outBuff.Length); SNINativeMethodWrapper.ConsumerInfo myInfo = CreateConsumerInfo(async); _sessionHandle = new SNIHandle(myInfo, physicalConnection); if (_sessionHandle.Status != TdsEnums.SNI_SUCCESS) { AddError(parser.ProcessSNIError(this)); ThrowExceptionAndWarning(); } // we post a callback that represents the call to dispose; once the // object is disposed, the next callback will cause the GC Handle to // be released. IncrementPendingCallbacks(); _lastSuccessfulIOTimer = parser._physicalStateObj._lastSuccessfulIOTimer; }
internal string BuildParamList(TdsParser parser, SqlParameterCollection parameters) { StringBuilder builder = new StringBuilder(); bool flag = false; bool isYukonOrNewer = parser.IsYukonOrNewer; int count = 0; count = parameters.Count; for (int i = 0; i < count; i++) { SqlParameter p = parameters[i]; p.Validate(i, System.Data.CommandType.StoredProcedure == this.CommandType); if (ShouldSendParameter(p)) { if (flag) { builder.Append(','); } builder.Append(p.ParameterNameFixed); MetaType internalMetaType = p.InternalMetaType; builder.Append(" "); if (internalMetaType.SqlDbType == SqlDbType.Udt) { string udtTypeName = p.UdtTypeName; if (ADP.IsEmpty(udtTypeName)) { throw SQL.MustSetUdtTypeNameForUdtParams(); } builder.Append(this.ParseAndQuoteIdentifier(udtTypeName, true)); } else if (internalMetaType.SqlDbType == SqlDbType.Structured) { string typeName = p.TypeName; if (ADP.IsEmpty(typeName)) { throw SQL.MustSetTypeNameForParam(internalMetaType.TypeName, p.ParameterNameFixed); } builder.Append(this.ParseAndQuoteIdentifier(typeName, false)); builder.Append(" READONLY"); } else { internalMetaType = p.ValidateTypeLengths(isYukonOrNewer); builder.Append(internalMetaType.TypeName); } flag = true; if (internalMetaType.SqlDbType == SqlDbType.Decimal) { byte actualPrecision = p.GetActualPrecision(); byte actualScale = p.GetActualScale(); builder.Append('('); if (actualPrecision == 0) { if (this.IsShiloh) { actualPrecision = 0x1d; } else { actualPrecision = 0x1c; } } builder.Append(actualPrecision); builder.Append(','); builder.Append(actualScale); builder.Append(')'); } else if (internalMetaType.IsVarTime) { byte num6 = p.GetActualScale(); builder.Append('('); builder.Append(num6); builder.Append(')'); } else if (((!internalMetaType.IsFixed && !internalMetaType.IsLong) && ((internalMetaType.SqlDbType != SqlDbType.Timestamp) && (internalMetaType.SqlDbType != SqlDbType.Udt))) && (SqlDbType.Structured != internalMetaType.SqlDbType)) { int size = p.Size; builder.Append('('); if (internalMetaType.IsAnsiType) { object coercedValue = p.GetCoercedValue(); string str = null; if ((coercedValue != null) && (DBNull.Value != coercedValue)) { str = coercedValue as string; if (str == null) { SqlString str4 = (coercedValue is SqlString) ? ((SqlString) coercedValue) : SqlString.Null; if (!str4.IsNull) { str = str4.Value; } } } if (str != null) { int num4 = parser.GetEncodingCharLength(str, p.GetActualSize(), p.Offset, null); if (num4 > size) { size = num4; } } } if (size == 0) { size = internalMetaType.IsSizeInCharacters ? 0xfa0 : 0x1f40; } builder.Append(size); builder.Append(')'); } else if ((internalMetaType.IsPlp && (internalMetaType.SqlDbType != SqlDbType.Xml)) && (internalMetaType.SqlDbType != SqlDbType.Udt)) { builder.Append("(max) "); } if (p.Direction != ParameterDirection.Input) { builder.Append(" output"); } } } return builder.ToString(); }
// Attempt to login to a host that has a failover partner // // Connection & timeout sequence is // First target, timeout = interval * 1 // second target, timeout = interval * 1 // sleep for 100ms // First target, timeout = interval * 2 // Second target, timeout = interval * 2 // sleep for 200ms // First Target, timeout = interval * 3 // etc. // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // DEVNOTE: The logic in this method is paralleled by the logic in LoginNoFailover. // Changes to either one should be examined to see if they need to be reflected in the other // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! private void LoginWithFailover( bool useFailoverHost, ServerInfo primaryServerInfo, string failoverHost, string newPassword, SecureString newSecurePassword, bool redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout ) { Debug.Assert(!connectionOptions.MultiSubnetFailover, "MultiSubnetFailover should not be set if failover partner is used"); if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, useFailover=%d{bool}, primary=", ObjectID, useFailoverHost); Bid.PutStr(primaryServerInfo.UserServerName); Bid.PutStr(", failover="); Bid.PutStr(failoverHost); Bid.PutStr("\n"); } int sleepInterval = 100; //milliseconds to sleep (back off) between attempts. long timeoutUnitInterval; string protocol = ConnectionOptions.NetworkLibrary; ServerInfo failoverServerInfo = new ServerInfo(connectionOptions, failoverHost); ResolveExtendedServerName(primaryServerInfo, !redirectedUserInstance, connectionOptions); if (null == ServerProvidedFailOverPartner) {// No point in resolving the failover partner when we're going to override it below // Don't resolve aliases if failover == primary // ResolveExtendedServerName(failoverServerInfo, !redirectedUserInstance && failoverHost != primaryServerInfo.UserServerName, connectionOptions); } // Determine unit interval if (timeout.IsInfinite) { timeoutUnitInterval = checked((long) ADP.FailoverTimeoutStep * ADP.TimerFromSeconds(ADP.DefaultConnectionTimeout)); } else { timeoutUnitInterval = checked((long) (ADP.FailoverTimeoutStep * timeout.MillisecondsRemaining)); } // Initialize loop variables bool failoverDemandDone = false; // have we demanded for partner information yet (as necessary)? int attemptNumber = 0; // Only three ways out of this loop: // 1) Successfully connected // 2) Parser threw exception while main timer was expired // 3) Parser threw logon failure-related exception (LOGON_FAILED, PASSWORD_EXPIRED, etc) // // Of these methods, only #1 exits normally. This preserves the call stack on the exception // back into the parser for the error cases. while (true) { // Set timeout for this attempt, but don't exceed original timer long nextTimeoutInterval = checked(timeoutUnitInterval * ((attemptNumber / 2) + 1)); long milliseconds = timeout.MillisecondsRemaining; if (nextTimeoutInterval > milliseconds) { nextTimeoutInterval = milliseconds; } TimeoutTimer intervalTimer = TimeoutTimer.StartMillisecondsTimeout(nextTimeoutInterval); // Re-allocate parser each time to make sure state is known // RFC 50002652 - if parser was created by previous attempt, dispose it to properly close the socket, if created if (_parser != null) _parser.Disconnect(); _parser = new TdsParser(ConnectionOptions.MARS, ConnectionOptions.Asynchronous); Debug.Assert(SniContext.Undefined== Parser._physicalStateObj.SniContext, String.Format((IFormatProvider)null, "SniContext should be Undefined; actual Value: {0}", Parser._physicalStateObj.SniContext)); ServerInfo currentServerInfo; if (useFailoverHost) { if (!failoverDemandDone) { FailoverPermissionDemand(); failoverDemandDone = true; } // Primary server may give us a different failover partner than the connection string indicates. Update it if (null != ServerProvidedFailOverPartner && failoverServerInfo.ResolvedServerName != ServerProvidedFailOverPartner) { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, new failover partner=%ls\n", ObjectID, ServerProvidedFailOverPartner); } failoverServerInfo.SetDerivedNames(protocol, ServerProvidedFailOverPartner); } currentServerInfo = failoverServerInfo; timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Failover); } else { currentServerInfo = primaryServerInfo; timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Principle); } try { // Attempt login. Use timerInterval for attempt timeout unless infinite timeout was requested. AttemptOneLogin( currentServerInfo, newPassword, newSecurePassword, false, // Use timeout in SniOpen intervalTimer, withFailover:true ); if (_routingInfo != null) { // We are in login with failover scenation and server sent routing information // If it is read-only routing - we did not supply AppIntent=RO (it should be checked before) // If it is something else, not known yet (future server) - this client is not designed to support this. // In any case, server should not have sent the routing info. Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover> Routed to %ls", _routingInfo.ServerName); throw SQL.ROR_UnexpectedRoutingInfo(this); } break; // leave the while loop -- we've successfully connected } catch (SqlException sqlex) { if (IsDoNotRetryConnectError(sqlex) || timeout.IsExpired) { // no more time to try again throw; // Caller will call LoginFailure() } if (IsConnectionDoomed) { throw; } if (1 == attemptNumber % 2) { // Check sleep interval to make sure we won't exceed the original timeout // Do this in the catch block so we can re-throw the current exception if (timeout.MillisecondsRemaining <= sleepInterval) { throw; } } // } // We only get here when we failed to connect, but are going to re-try // After trying to connect to both servers fails, sleep for a bit to prevent clogging // the network with requests, then update sleep interval for next iteration (max 1 second interval) if (1 == attemptNumber % 2) { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, sleeping %d{milisec}\n", ObjectID, sleepInterval); } Thread.Sleep(sleepInterval); sleepInterval = (sleepInterval < 500) ? sleepInterval * 2 : 1000; } // Update attempt number and target host attemptNumber++; useFailoverHost = !useFailoverHost; } // If we get here, connection/login succeeded! Just a few more checks & record-keeping // if connected to failover host, but said host doesn't have DbMirroring set up, throw an error if (useFailoverHost && null == ServerProvidedFailOverPartner) { throw SQL.InvalidPartnerConfiguration(failoverHost, CurrentDatabase); } if (null != PoolGroupProviderInfo) { // We must wait for CompleteLogin to finish for to have the // env change from the server to know its designated failover // partner; save this information in _currentFailoverPartner. PoolGroupProviderInfo.FailoverCheck(this, useFailoverHost, connectionOptions, ServerProvidedFailOverPartner); } CurrentDataSource = (useFailoverHost ? failoverHost : primaryServerInfo.UserServerName); }
public TdsParserStateObject CreateTdsParserStateObject(TdsParser parser) { return(new TdsParserStateObjectManaged(parser)); }
private readonly WritePacketCache _writePacketCache = new WritePacketCache(); // Store write packets that are ready to be re-used public TdsParserStateObjectNative(TdsParser parser) : base(parser) { }
private void EnlistNonNull(Transaction tx) { Debug.Assert(null != tx, "null transaction?"); bool hasDelegatedTransaction = false; // Promotable transactions are only supported on Yukon // servers or newer. SqlDelegatedTransaction delegatedTransaction = new SqlDelegatedTransaction(this, tx); try { // NOTE: System.Transactions claims to resolve all // potential race conditions between multiple delegate // requests of the same transaction to different // connections in their code, such that only one // attempt to delegate will succeed. // NOTE: PromotableSinglePhaseEnlist will eventually // make a round trip to the server; doing this inside // a lock is not the best choice. We presume that you // aren't trying to enlist concurrently on two threads // and leave it at that -- We don't claim any thread // safety with regard to multiple concurrent requests // to enlist the same connection in different // transactions, which is good, because we don't have // it anyway. // PromotableSinglePhaseEnlist may not actually promote // the transaction when it is already delegated (this is // the way they resolve the race condition when two // threads attempt to delegate the same Lightweight // Transaction) In that case, we can safely ignore // our delegated transaction, and proceed to enlist // in the promoted one. // NOTE: Global Transactions is an Azure SQL DB only // feature where the Transaction Manager (TM) is not // MS-DTC. Sys.Tx added APIs to support Non MS-DTC // promoter types/TM in .NET 4.6.1. Following directions // from .NETFX shiproom, to avoid a "hard-dependency" // (compile time) on Sys.Tx, we use reflection to invoke // the new APIs. Further, the _isGlobalTransaction flag // indicates that this is an Azure SQL DB Transaction // that could be promoted to a Global Transaction (it's // always false for on-prem Sql Server). The Promote() // call in SqlDelegatedTransaction makes sure that the // right Sys.Tx.dll is loaded and that Global Transactions // are actually allowed for this Azure SQL DB. if (_isGlobalTransaction) { if (SysTxForGlobalTransactions.EnlistPromotableSinglePhase == null) { // This could be a local Azure SQL DB transaction. hasDelegatedTransaction = tx.EnlistPromotableSinglePhase(delegatedTransaction); } else { hasDelegatedTransaction = (bool)SysTxForGlobalTransactions.EnlistPromotableSinglePhase.Invoke(tx, new object[] { delegatedTransaction, _globalTransactionTMID }); } } else { // This is an MS-DTC distributed transaction hasDelegatedTransaction = tx.EnlistPromotableSinglePhase(delegatedTransaction); } if (hasDelegatedTransaction) { this.DelegatedTransaction = delegatedTransaction; } } catch (SqlException e) { // we do not want to eat the error if it is a fatal one if (e.Class >= TdsEnums.FATAL_ERROR_CLASS) { throw; } // if the parser is null or its state is not openloggedin, the connection is no longer good. SqlInternalConnectionTds tdsConnection = this as SqlInternalConnectionTds; if (tdsConnection != null) { TdsParser parser = tdsConnection.Parser; if (parser == null || parser.State != TdsParserState.OpenLoggedIn) { throw; } } // In this case, SqlDelegatedTransaction.Initialize // failed and we don't necessarily want to reject // things -- there may have been a legitimate reason // for the failure. } if (!hasDelegatedTransaction) { byte[] cookie = null; if (_isGlobalTransaction) { if (SysTxForGlobalTransactions.GetPromotedToken == null) { throw SQL.UnsupportedSysTxForGlobalTransactions(); } cookie = (byte[])SysTxForGlobalTransactions.GetPromotedToken.Invoke(tx, null); } else { if (null == _whereAbouts) { byte[] dtcAddress = GetDTCAddress(); if (null == dtcAddress) { throw SQL.CannotGetDTCAddress(); } _whereAbouts = dtcAddress; } cookie = GetTransactionCookie(tx, _whereAbouts); } // send cookie to server to finish enlistment PropagateTransactionCookie(cookie); _isEnlistedInTransaction = true; } EnlistedTransaction = tx; // Tell the base class about our enlistment // If we're on a Yukon or newer server, and we delegate the // transaction successfully, we will have done a begin transaction, // which produces a transaction id that we should execute all requests // on. The TdsParser or SmiEventSink will store this information as // the current transaction. // // Likewise, propagating a transaction to a Yukon or newer server will // produce a transaction id that The TdsParser or SmiEventSink will // store as the current transaction. // // In either case, when we're working with a Yukon or newer server // we better have a current transaction by now. Debug.Assert(null != CurrentTransaction, "delegated/enlisted transaction with null current transaction?"); }
private void WriteToServerInternal() { string tDSCommand = null; bool flag3 = false; bool flag2 = false; int[] useSqlValue = null; int num5 = this._batchSize; bool flag4 = false; if (this._batchSize > 0) { flag4 = true; } Exception inner = null; this._rowsCopied = 0; if (this._destinationTableName == null) { throw SQL.BulkLoadMissingDestinationTable(); } if (this.ReadFromRowSource()) { RuntimeHelpers.PrepareConstrainedRegions(); try { bool flag = true; this._parser = this._connection.Parser; this._stateObj = this._parser.GetSession(this); this._stateObj._bulkCopyOpperationInProgress = true; try { BulkCopySimpleResultSet set; this._stateObj.StartSession(this.ObjectID); try { set = this.CreateAndExecuteInitialQuery(); } catch (SqlException exception5) { throw SQL.BulkLoadInvalidDestinationTable(this._destinationTableName, exception5); } this._rowsUntilNotification = this._notifyAfter; tDSCommand = this.AnalyzeTargetAndCreateUpdateBulkCommand(set); if (this._sortedColumnMappings.Count == 0) { return; } this._stateObj.SniContext = SniContext.Snix_SendRows; Label_00DD: if (this.IsCopyOption(SqlBulkCopyOptions.UseInternalTransaction)) { this._internalTransaction = this._connection.BeginTransaction(); } this.SubmitUpdateBulkCommand(set, tDSCommand); try { this.WriteMetaData(set); object[] objArray = new object[this._sortedColumnMappings.Count]; if (useSqlValue == null) { useSqlValue = new int[objArray.Length]; } int num3 = num5; do { for (int i = 0; i < objArray.Length; i++) { _ColumnMapping mapping = (_ColumnMapping) this._sortedColumnMappings[i]; _SqlMetaData metadata = mapping._metadata; object obj2 = this.GetValueFromSourceRow(mapping._sourceColumnOrdinal, metadata, useSqlValue, i); objArray[i] = this.ConvertValue(obj2, metadata); } this._parser.WriteByte(0xd1, this._stateObj); for (int j = 0; j < objArray.Length; j++) { _ColumnMapping mapping2 = (_ColumnMapping) this._sortedColumnMappings[j]; _SqlMetaData data = mapping2._metadata; if (data.type != SqlDbType.Variant) { this._parser.WriteBulkCopyValue(objArray[j], data, this._stateObj); } else { this._parser.WriteSqlVariantDataRowValue(objArray[j], this._stateObj); } } this._rowsCopied++; if (((this._notifyAfter > 0) && (this._rowsUntilNotification > 0)) && (--this._rowsUntilNotification == 0)) { try { this._stateObj.BcpLock = true; flag2 = this.FireRowsCopiedEvent((long) this._rowsCopied); Bid.Trace("<sc.SqlBulkCopy.WriteToServerInternal|INFO> \n"); if (ConnectionState.Open != this._connection.State) { goto Label_02F7; } } catch (Exception exception2) { if (!ADP.IsCatchableExceptionType(exception2)) { throw; } inner = OperationAbortedException.Aborted(exception2); goto Label_02F7; } finally { this._stateObj.BcpLock = false; } if (flag2) { goto Label_02F7; } this._rowsUntilNotification = this._notifyAfter; } if (this._rowsUntilNotification > this._notifyAfter) { this._rowsUntilNotification = this._notifyAfter; } flag3 = this.ReadFromRowSource(); if (flag4) { num3--; if (num3 == 0) { goto Label_02F7; } } } while (flag3); } catch (NullReferenceException) { this._stateObj.CancelRequest(); throw; } catch (Exception exception4) { if (ADP.IsCatchableExceptionType(exception4)) { this._stateObj.CancelRequest(); } throw; } Label_02F7: if (ConnectionState.Open != this._connection.State) { throw ADP.OpenConnectionRequired("WriteToServer", this._connection.State); } this._parser.WriteBulkCopyDone(this._stateObj); this._parser.Run(RunBehavior.UntilDone, null, null, null, this._stateObj); if (flag2 || (inner != null)) { throw OperationAbortedException.Aborted(inner); } if (this._internalTransaction != null) { this._internalTransaction.Commit(); this._internalTransaction = null; } if (flag3) { goto Label_00DD; } this._localColumnMappings = null; } catch (Exception exception3) { flag = ADP.IsCatchableExceptionType(exception3); if (flag) { this._stateObj._internalTimeout = false; if (this._internalTransaction != null) { if (!this._internalTransaction.IsZombied) { this._internalTransaction.Rollback(); } this._internalTransaction = null; } } throw; } finally { if (flag && (this._stateObj != null)) { this._stateObj.CloseSession(); } } } finally { if (this._stateObj != null) { this._stateObj._bulkCopyOpperationInProgress = false; this._stateObj = null; } } } }