public void Initialize() { // if we get here, then we know for certain that we're the delegated // transaction. SqlInternalConnection connection = _connection; SqlConnection usersConnection = connection.Connection; Bid.Trace("<sc.SqlDelegatedTransaction.Initialize|RES|CPOOL> %d#, Connection %d#, delegating transaction.\n", ObjectID, connection.ObjectID); RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif //DEBUG if (connection.IsEnlistedInTransaction) { // defect first Bid.Trace("<sc.SqlDelegatedTransaction.Initialize|RES|CPOOL> %d#, Connection %d#, was enlisted, now defecting.\n", ObjectID, connection.ObjectID); connection.EnlistNull(); } _internalTransaction = new SqlInternalTransaction(connection, TransactionType.Delegated, null); connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Begin, null, _isolationLevel, _internalTransaction, true); // Handle case where ExecuteTran didn't produce a new transaction, but also didn't throw. if (null == connection.CurrentTransaction) { connection.DoomThisConnection(); throw ADP.InternalError(ADP.InternalErrorCode.UnknownTransactionFailure); } _active = true; } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException e) { usersConnection.Abort(e); throw; } catch (System.StackOverflowException e) { usersConnection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { usersConnection.Abort(e); throw; } }
// Called by the transaction to initiate commit sequence public void SinglePhaseCommit(SysTx.SinglePhaseEnlistment enlistment) { Debug.Assert(null != enlistment, "null enlistment?"); SqlInternalConnection connection = GetValidConnection(); SqlConnection usersConnection = connection.Connection; Bid.Trace("<sc.SqlDelegatedTransaction.SinglePhaseCommit|RES|CPOOL> %d#, Connection %d#, committing transaction.\n", ObjectID, connection.ObjectID); RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif //DEBUG // If the connection is dooomed, we can be certain that the // transaction will eventually be rolled back, and we shouldn't // attempt to commit it. if (connection.IsConnectionDoomed) { lock (connection) { _active = false; // set to inactive first, doesn't matter how the rest completes, this transaction is done. _connection = null; } enlistment.Aborted(SQL.ConnectionDoomed()); } else { Exception commitException; lock (connection) { try { // Now that we've acquired the lock, make sure we still have valid state for this operation. ValidateActiveOnConnection(connection); _active = false; // set to inactive first, doesn't matter how the rest completes, this transaction is done. _connection = null; // Set prior to ExecuteTransaction call in case this initiates a TransactionEnd event connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Commit, null, IsolationLevel.Unspecified, _internalTransaction, true); commitException = null; } catch (SqlException e) { commitException = e; ADP.TraceExceptionWithoutRethrow(e); // Doom the connection, to make sure that the transaction is // eventually rolled back. // VSTS 144562: doom the connection while having the lock on it to prevent race condition with "Transaction Ended" Event connection.DoomThisConnection(); } catch (InvalidOperationException e) { commitException = e; ADP.TraceExceptionWithoutRethrow(e); connection.DoomThisConnection(); } } if (commitException != null) { // connection.ExecuteTransaction failed with exception if (_internalTransaction.IsCommitted) { // Even though we got an exception, the transaction // was committed by the server. enlistment.Committed(); } else if (_internalTransaction.IsAborted) { // The transaction was aborted, report that to // SysTx. enlistment.Aborted(commitException); } else { // The transaction is still active, we cannot // know the state of the transaction. enlistment.InDoubt(commitException); } // We eat the exception. This is called on the SysTx // thread, not the applications thread. If we don't // eat the exception an UnhandledException will occur, // causing the process to FailFast. } connection.CleanupConnectionOnTransactionCompletion(_atomicTransaction); if (commitException == null) { // connection.ExecuteTransaction succeeded enlistment.Committed(); } } } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException e) { usersConnection.Abort(e); throw; } catch (System.StackOverflowException e) { usersConnection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { usersConnection.Abort(e); throw; } }
// Called by transaction to initiate abort sequence public void Rollback(SysTx.SinglePhaseEnlistment enlistment) { Debug.Assert(null != enlistment, "null enlistment?"); SqlInternalConnection connection = GetValidConnection(); SqlConnection usersConnection = connection.Connection; Bid.Trace("<sc.SqlDelegatedTransaction.Rollback|RES|CPOOL> %d#, Connection %d#, aborting transaction.\n", ObjectID, connection.ObjectID); RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif //DEBUG lock (connection) { try { // Now that we've acquired the lock, make sure we still have valid state for this operation. ValidateActiveOnConnection(connection); _active = false; // set to inactive first, doesn't matter how the execute completes, this transaction is done. _connection = null; // Set prior to ExecuteTransaction call in case this initiates a TransactionEnd event // If we haven't already rolled back (or aborted) then tell the SQL Server to roll back if (!_internalTransaction.IsAborted) { connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Rollback, null, IsolationLevel.Unspecified, _internalTransaction, true); } } catch (SqlException e) { ADP.TraceExceptionWithoutRethrow(e); // Doom the connection, to make sure that the transaction is // eventually rolled back. // VSTS 144562: doom the connection while having the lock on it to prevent race condition with "Transaction Ended" Event connection.DoomThisConnection(); // Unlike SinglePhaseCommit, a rollback is a rollback, regardless // of how it happens, so SysTx won't throw an exception, and we // don't want to throw an exception either, because SysTx isn't // handling it and it may create a fail fast scenario. In the end, // there is no way for us to communicate to the consumer that this // failed for more serious reasons than usual. // // This is a bit like "should you throw if Close fails", however, // it only matters when you really need to know. In that case, // we have the tracing that we're doing to fallback on for the // investigation. } catch (InvalidOperationException e) { ADP.TraceExceptionWithoutRethrow(e); connection.DoomThisConnection(); } } // it doesn't matter whether the rollback succeeded or not, we presume // that the transaction is aborted, because it will be eventually. connection.CleanupConnectionOnTransactionCompletion(_atomicTransaction); enlistment.Aborted(); } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException e) { usersConnection.Abort(e); throw; } catch (System.StackOverflowException e) { usersConnection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { usersConnection.Abort(e); throw; } }
public Byte [] Promote() { // Operations that might be affected by multi-threaded use MUST be done inside the lock. // Don't read values off of the connection outside the lock unless it doesn't really matter // from an operational standpoint (i.e. logging connection's ObjectID should be fine, // but the PromotedDTCToken can change over calls. so that must be protected). SqlInternalConnection connection = GetValidConnection(); Exception promoteException; byte[] returnValue = null; SqlConnection usersConnection = connection.Connection; Bid.Trace("<sc.SqlDelegatedTransaction.Promote|RES|CPOOL> %d#, Connection %d#, promoting transaction.\n", ObjectID, connection.ObjectID); RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif //DEBUG lock (connection) { try { // Now that we've acquired the lock, make sure we still have valid state for this operation. ValidateActiveOnConnection(connection); connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Promote, null, IsolationLevel.Unspecified, _internalTransaction, true); returnValue = _connection.PromotedDTCToken; promoteException = null; } catch (SqlException e) { promoteException = e; ADP.TraceExceptionWithoutRethrow(e); // Doom the connection, to make sure that the transaction is // eventually rolled back. // VSTS 144562: doom the connection while having the lock on it to prevent race condition with "Transaction Ended" Event connection.DoomThisConnection(); } catch (InvalidOperationException e) { promoteException = e; ADP.TraceExceptionWithoutRethrow(e); connection.DoomThisConnection(); } } } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException e) { usersConnection.Abort(e); throw; } catch (System.StackOverflowException e) { usersConnection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { usersConnection.Abort(e); throw; } if (promoteException != null) { throw SQL.PromotionFailed(promoteException); } return returnValue; }
private void ResetCancelAndProcessAttention() { // This method is shared by CloseSession initiated by DataReader.Close or completed // command execution, as well as the session reclaimation code for cases where the // DataReader is opened and then GC'ed. lock(this) { // Reset cancel state. _cancelled = false; _allowObjectID = -1; if (_attentionSent) { // Make sure we're cleaning up the AttentionAck if Cancel happened before taking the lock. // We serialize Cancel/CloseSession to prevent a race condition between these two states. // The problem is that both sending and receiving attentions are time taking // operations. #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #endif //DEBUG Parser.ProcessPendingAck(this); #if DEBUG } finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } _internalTimeout = false; } }
public void Save(string savePointName) { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, "<sc.SqlTransaction.Save|API> %d# savePointName='%ls'", ObjectID, savePointName); 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); _internalTransaction.Save(savePointName); } #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); Bid.ScopeLeave(ref hscp); } }
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); } }
// 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); } }
private void ExecuteFlushTaskCallback(Task tsk, TdsParserStateObject stateObj, TaskCompletionSource<object> completion, bool releaseConnectionLock) { try { FinalizeExecuteRPC(stateObj); if (tsk.Exception != null) { Exception exc = tsk.Exception.InnerException; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif //DEBUG FailureCleanup(stateObj, tsk.Exception); } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connHandler.DoomThisConnection(); completion.SetException(e); throw; } catch (System.StackOverflowException e) { _connHandler.DoomThisConnection(); completion.SetException(e); throw; } catch (System.Threading.ThreadAbortException e) { _connHandler.DoomThisConnection(); completion.SetException(e); throw; } catch (Exception e) { exc = e; } completion.SetException(exc); } else { completion.SetResult(null); } } finally { if (releaseConnectionLock) { _connHandler._parserLock.Release(); } } }
private void TdsExecuteRPC_OnFailure(Exception exc, TdsParserStateObject stateObj) { RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif //DEBUG FailureCleanup(stateObj, exc); } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException) { _connHandler.DoomThisConnection(); throw; } catch (System.StackOverflowException) { _connHandler.DoomThisConnection(); throw; } catch (System.Threading.ThreadAbortException) { _connHandler.DoomThisConnection(); throw; } }
internal void DrainData(TdsParserStateObject stateObj) { RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif //DEBUG try { SqlDataReader.SharedState sharedState = stateObj._readerState; if (sharedState != null && sharedState._dataReady) { var metadata = stateObj._cleanupMetaData; if (stateObj._partialHeaderBytesRead > 0) { if (!stateObj.TryProcessHeader()) { throw SQL.SynchronousCallMayNotPend(); } } if (0 == sharedState._nextColumnHeaderToRead) { // i. user called read but didn't fetch anything if (!stateObj.Parser.TrySkipRow(stateObj._cleanupMetaData, stateObj)) { throw SQL.SynchronousCallMayNotPend(); } } else { // iia. if we still have bytes left from a partially read column, skip if (sharedState._nextColumnDataToRead < sharedState._nextColumnHeaderToRead) { if ((sharedState._nextColumnHeaderToRead > 0) && (metadata[sharedState._nextColumnHeaderToRead - 1].metaType.IsPlp)) { if (stateObj._longlen != 0) { ulong ignored; if (!TrySkipPlpValue(UInt64.MaxValue, stateObj, out ignored)) { throw SQL.SynchronousCallMayNotPend(); } } } else if (0 < sharedState._columnDataBytesRemaining) { if (!stateObj.TrySkipLongBytes(sharedState._columnDataBytesRemaining)) { throw SQL.SynchronousCallMayNotPend(); } } } // iib. // now read the remaining values off the wire for this row if (!stateObj.Parser.TrySkipRow(metadata, sharedState._nextColumnHeaderToRead, stateObj)) { throw SQL.SynchronousCallMayNotPend(); } } } Run(RunBehavior.Clean, null, null, null, stateObj); } catch { _connHandler.DoomThisConnection(); throw; } } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException) { _connHandler.DoomThisConnection(); throw; } catch (System.StackOverflowException) { _connHandler.DoomThisConnection(); throw; } catch (System.Threading.ThreadAbortException) { _connHandler.DoomThisConnection(); throw; } }
internal bool RunReliably(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) { RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #endif //DEBUG return Run(runBehavior, cmdHandler, dataStream, bulkCopyHandler, stateObj); #if DEBUG } finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (OutOfMemoryException) { _connHandler.DoomThisConnection(); throw; } catch (StackOverflowException) { _connHandler.DoomThisConnection(); throw; } catch (ThreadAbortException) { _connHandler.DoomThisConnection(); throw; } }
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { Debug.Assert(_parser._asyncWrite); ValidateWriteParameters(buffer, offset, count); StripPreamble(buffer, ref offset, ref count); RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #else { #endif //DEBUG Task task = null; if (count > 0) { _parser.WriteInt(count, _stateObj); // write length of chunk task = _stateObj.WriteByteArray(buffer, count, offset, canAccumulate: false); } if (task == null) { return CompletedTask; } else { return task; } } #if DEBUG finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException) { _parser._connHandler.DoomThisConnection(); throw; } catch (System.StackOverflowException) { _parser._connHandler.DoomThisConnection(); throw; } catch (System.Threading.ThreadAbortException) { _parser._connHandler.DoomThisConnection(); throw; } }
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; } }
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); } }
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); }
// called by SqlConnection.RepairConnection which is a relatevly expensive way of repair inner connection // prior to execution of request, used from EnlistTransaction, EnlistDistributedTransaction and ChangeDatabase internal bool GetSessionAndReconnectIfNeeded(SqlConnection parent, int timeout = 0) { Debug.Assert(!ThreadHasParserLockForClose, "Cannot call this method if caller has parser lock"); if (ThreadHasParserLockForClose) { return false; // we cannot restore if we cannot release lock } _parserLock.Wait(canReleaseFromAnyThread: false); ThreadHasParserLockForClose = true; // In case of error, let the connection know that we already own the parser lock bool releaseConnectionLock = true; try { RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #endif //DEBUG Task reconnectTask = parent.ValidateAndReconnect(() => { ThreadHasParserLockForClose = false; _parserLock.Release(); releaseConnectionLock = false; }, timeout); if (reconnectTask != null) { AsyncHelper.WaitForCompletion(reconnectTask, timeout); return true; } return false; #if DEBUG } finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (System.OutOfMemoryException) { DoomThisConnection(); throw; } catch (System.StackOverflowException) { DoomThisConnection(); throw; } catch (System.Threading.ThreadAbortException) { DoomThisConnection(); throw; } } finally { if (releaseConnectionLock) { ThreadHasParserLockForClose = false; _parserLock.Release(); } } }
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 override bool IsConnectionAlive(bool throwOnException) { bool isAlive = false; #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #endif //DEBUG isAlive = _parser._physicalStateObj.IsConnectionAlive(throwOnException); #if DEBUG } finally { tdsReliabilitySection.Stop(); } #endif //DEBUG return isAlive; }
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; } }