/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlFileStream.xml' path='docs/members[@name="SqlFileStream"]/ctor2/*' /> public SqlFileStream(string path, byte[] transactionContext, FileAccess access, FileOptions options, long allocationSize) { using (TryEventScope.Create(SqlClientEventSource.Log.TryScopeEnterEvent("SqlFileStream.ctor | API | Object Id {0} | Access {1} | Options {2} | Path '{3}'", ObjectID, (int)access, (int)options, path))) { //----------------------------------------------------------------- // precondition validation if (transactionContext == null) { throw ADP.ArgumentNull("transactionContext"); } if (path == null) { throw ADP.ArgumentNull("path"); } //----------------------------------------------------------------- _m_disposed = false; _m_fs = null; OpenSqlFileStream(path, transactionContext, access, options, allocationSize); // only set internal state once the file has actually been successfully opened Name = path; TransactionContext = transactionContext; } }
internal void Save(string savePointName) { using (TryEventScope.Create("<sc.SqlInternalTransaction.Save|API> {0}, savePointName='{1}'", ObjectID, savePointName)) { _innerConnection.ValidateConnectionForExecute(null); // ROLLBACK takes either a save point name or a transaction name. It will rollback the // transaction to either the save point with the save point name or begin with the // transaction name. So, to rollback a nested transaction you must have a save point. // SAVE TRANSACTION MUST HAVE AN ARGUMENT!!! Save Transaction without an arg throws an // exception from the server. So, an overload for SaveTransaction without an arg doesn't make // sense to have. Save Transaction does not affect the transaction level. if (ADP.IsEmpty(savePointName)) { throw SQL.NullEmptyTransactionName(); } try { _innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Save, savePointName, IsolationLevel.Unspecified, null, false); } catch (Exception e) { // UNDONE - should not be catching all exceptions!!! if (ADP.IsCatchableExceptionType(e)) { CheckTransactionLevelAndZombie(); } throw; } } }
internal void Rollback(string transactionName) { using (TryEventScope.Create("SqlInternalTransaction.Rollback | API | Object Id {0}, Transaction Name {1}", ObjectID, transactionName)) { if (_innerConnection.IsLockedForBulkCopy) { throw SQL.ConnectionLockedForBcpEvent(); } _innerConnection.ValidateConnectionForExecute(null); // ROLLBACK takes either a save point name or a transaction name. It will rollback the // transaction to either the save point with the save point name or begin with the // transaction name. NOTE: for simplicity it is possible to give all save point names // the same name, and ROLLBACK will simply rollback to the most recent save point with the // save point name. if (string.IsNullOrEmpty(transactionName)) { throw SQL.NullEmptyTransactionName(); } try { _innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Rollback, transactionName, IsolationLevel.Unspecified, null, false); } catch (Exception e) { if (ADP.IsCatchableExceptionType(e)) { CheckTransactionLevelAndZombie(); } throw; } } }
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/RollbackTransactionName/*' /> public void Rollback(string transactionName) { using (DiagnosticTransactionScope diagnosticScope = s_diagnosticListener.CreateTransactionRollbackScope(_isolationLevel, _connection, InternalTransaction, transactionName)) { ZombieCheck(); using (TryEventScope.Create(SqlClientEventSource.Log.TryScopeEnterEvent("SqlTransaction.Rollback | API | Object Id {0}, Transaction Name='{1}', ActivityID {2}, Client Connection Id {3}", ObjectID, transactionName, ActivityCorrelator.Current, Connection?.ClientConnectionId))) { SqlStatistics statistics = null; try { statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Rollback(transactionName); } catch (Exception ex) { diagnosticScope.SetException(ex); throw; } finally { SqlStatistics.StopTimer(statistics); _isFromAPI = false; } } } }
internal void Deactivate() { // When being deactivated, we check all the sessions in the // cache to make sure they're cleaned up and then we dispose of // sessions that are past what we want to keep around. using (TryEventScope.Create("<sc.TdsParserSessionPool.Deactivate|ADV> {0} deactivating cachedCount={1}", ObjectID, _cachedCount)) { lock (_cache) { // NOTE: The PutSession call below may choose to remove the // session from the cache, which will throw off our // enumerator. We avoid that by simply indexing backward // through the array. for (int i = _cache.Count - 1; i >= 0; i--) { TdsParserStateObject session = _cache[i]; if (null != session) { if (session.IsOrphaned) { // TODO: consider adding a performance counter for the number of sessions we reclaim SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParserSessionPool.Deactivate|ADV> {0} reclaiming session {1}", ObjectID, session.ObjectID); PutSession(session); } } } // TODO: re-enable this assert when the connection isn't doomed. //Debug.Assert (_cachedCount < MaxInactiveCount, "non-orphaned connection past initial allocation?"); } } }
internal void Commit() { using (TryEventScope.Create("SqlInternalTransaction.Commit | API | Object Id {0}", ObjectID)) { if (_innerConnection.IsLockedForBulkCopy) { throw SQL.ConnectionLockedForBcpEvent(); } _innerConnection.ValidateConnectionForExecute(null); // If this transaction has been completed, throw exception since it is unusable. try { // COMMIT ignores transaction names, and so there is no reason to pass it anything. COMMIT // simply commits the transaction from the most recent BEGIN, nested or otherwise. _innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Commit, null, IsolationLevel.Unspecified, null, false); { ZombieParent(); } } catch (Exception e) { if (ADP.IsCatchableExceptionType(e)) { CheckTransactionLevelAndZombie(); } throw; } } }
/// <include file='..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Save/*' /> public void Save(string savePointName) { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; using (TryEventScope.Create("<sc.SqlTransaction.Save|API> {0} savePointName='{1}'", 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); } } }
/// <include file='..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnection.xml' path='docs/members[@name="SqlConnection"]/CreateDbCommand/*' /> override protected DbCommand CreateDbCommand() { using (TryEventScope.Create("<prov.DbConnectionHelper.CreateDbCommand|API> {0}", ObjectID)) { DbProviderFactory providerFactory = ConnectionFactory.ProviderFactory; DbCommand command = providerFactory.CreateCommand(); command.Connection = this; return(command); } }
//////////////////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS //////////////////////////////////////////////////////////////////////////////////////// /// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Commit/*' /> override public void Commit() { Exception e = null; Guid operationId = s_diagnosticListener.WriteTransactionCommitBefore(_isolationLevel, _connection, InternalTransaction); ZombieCheck(); SqlStatistics statistics = null; using (TryEventScope.Create("SqlTransaction.Commit | API | Object Id {0}", ObjectID)) { SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlTransaction.Commit | API | Correlation | Object Id {0}, Activity Id {1}, Client Connection Id {2}", ObjectID, ActivityCorrelator.Current, Connection?.ClientConnectionId); try { statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Commit(); } catch (SqlException ex) { // GitHub Issue #130 - When a timeout exception has occurred on transaction completion request, // this connection may not be in reusable state. // We will abort this connection and make sure it does not go back to the pool. var innerException = ex.InnerException as Win32Exception; if (innerException != null && innerException.NativeErrorCode == TdsEnums.SNI_WAIT_TIMEOUT) { _connection.Abort(ex); } e = ex; throw; } catch (Exception ex) { e = ex; throw; } finally { SqlStatistics.StopTimer(statistics); if (e != null) { s_diagnosticListener.WriteTransactionCommitError(operationId, _isolationLevel, _connection, InternalTransaction, e); } else { s_diagnosticListener.WriteTransactionCommitAfter(operationId, _isolationLevel, _connection, InternalTransaction); } _isFromAPI = false; } } }
public void ClearPool(DbConnection connection) { ADP.CheckArgumentNull(connection, nameof(connection)); using (TryEventScope.Create("<prov.DbConnectionFactory.ClearPool|API> {0}", GetObjectId(connection))) { DbConnectionPoolGroup poolGroup = GetConnectionPoolGroup(connection); if (null != poolGroup) { poolGroup.Clear(); } } }
public void ClearPool(DbConnectionPoolKey key) { Debug.Assert(key != null, "key cannot be null"); ADP.CheckArgumentNull(key.ConnectionString, nameof(key) + "." + nameof(key.ConnectionString)); using (TryEventScope.Create("<prov.DbConnectionFactory.ClearPool|API> connectionString")) { Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> connectionPoolGroups = _connectionPoolGroups; if (connectionPoolGroups.TryGetValue(key, out DbConnectionPoolGroup poolGroup)) { poolGroup.Clear(); } } }
public void ClearAllPools() { using (TryEventScope.Create("<prov.DbConnectionFactory.ClearAllPools|API")) { Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> connectionPoolGroups = _connectionPoolGroups; foreach (KeyValuePair <DbConnectionPoolKey, DbConnectionPoolGroup> entry in connectionPoolGroups) { DbConnectionPoolGroup poolGroup = entry.Value; if (null != poolGroup) { poolGroup.Clear(); } } } }
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Rollback2/*' /> override public void Rollback() { Exception e = null; Guid operationId = s_diagnosticListener.WriteTransactionRollbackBefore(_isolationLevel, _connection, InternalTransaction); if (IsYukonPartialZombie) { // Put something in the trace in case a customer has an issue SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Rollback | ADV | Object Id {0}, partial zombie no rollback required", ObjectID); _internalTransaction = null; // yukon zombification } else { ZombieCheck(); SqlStatistics statistics = null; using (TryEventScope.Create("SqlTransaction.Rollback | API | Object Id {0}", ObjectID)) { SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlTransaction.Rollback | API | Correlation | Object Id {0}, ActivityID {1}, Client Connection Id {2}", ObjectID, ActivityCorrelator.Current, Connection?.ClientConnectionId); try { statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Rollback(); } catch (Exception ex) { e = ex; throw; } finally { SqlStatistics.StopTimer(statistics); if (e != null) { s_diagnosticListener.WriteTransactionRollbackError(operationId, _isolationLevel, _connection, InternalTransaction, e); } else { s_diagnosticListener.WriteTransactionRollbackAfter(operationId, _isolationLevel, _connection, InternalTransaction); } _isFromAPI = false; } } } }
internal int ExecuteNonQuery() { ValidateCommandBehavior(nameof(ExecuteNonQuery), CommandBehavior.Default); using (TryEventScope.Create("SqlCommandSet.ExecuteNonQuery | API | Object Id {0}, Commands executed in Batch RPC mode", ObjectID)) { BatchCommand.BatchRPCMode = true; BatchCommand.ClearBatchCommand(); BatchCommand.Parameters.Clear(); for (int ii = 0; ii < _commandList.Count; ii++) { LocalCommand cmd = _commandList[ii]; BatchCommand.AddBatchCommand(cmd.CommandText, cmd.Parameters, cmd.CmdType, cmd.ColumnEncryptionSetting); } return(BatchCommand.ExecuteBatchRPCCommand()); } }
internal void Rollback(string transactionName) { using (TryEventScope.Create("<sc.SqlInternalTransaction.Rollback|API> {0}, transactionName='{1}'", ObjectID, transactionName)) { if (_innerConnection.IsLockedForBulkCopy) { throw SQL.ConnectionLockedForBcpEvent(); } _innerConnection.ValidateConnectionForExecute(null); // ROLLBACK takes either a save point name or a transaction name. It will rollback the // transaction to either the save point with the save point name or begin with the // transaction name. NOTE: for simplicity it is possible to give all save point names // the same name, and ROLLBACK will simply rollback to the most recent save point with the // save point name. if (ADP.IsEmpty(transactionName)) { throw SQL.NullEmptyTransactionName(); } try { _innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Rollback, transactionName, IsolationLevel.Unspecified, null, false); if (!IsZombied && !_innerConnection.Is2005OrNewer) { // Check if Zombied before making round-trip to server. // Against 2005 we receive an envchange on the ExecuteTransaction above on the // parser that calls back into SqlTransaction for the Zombie() call. CheckTransactionLevelAndZombie(); } } catch (Exception e) { // UNDONE - should not be catching all exceptions!!! if (ADP.IsCatchableExceptionType(e)) { CheckTransactionLevelAndZombie(); } throw; } } }
internal void Commit() { using (TryEventScope.Create("<sc.SqlInternalTransaction.Commit|API> {0}", ObjectID)) { if (_innerConnection.IsLockedForBulkCopy) { throw SQL.ConnectionLockedForBcpEvent(); } _innerConnection.ValidateConnectionForExecute(null); // If this transaction has been completed, throw exception since it is unusable. try { // COMMIT ignores transaction names, and so there is no reason to pass it anything. COMMIT // simply commits the transaction from the most recent BEGIN, nested or otherwise. _innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Commit, null, IsolationLevel.Unspecified, null, false); // SQL BU DT 291159 - perform full Zombie on pre-2005, but do not actually // complete internal transaction until informed by server in the case of 2005 // or later. if (!IsZombied && !_innerConnection.Is2005OrNewer) { // Since nested transactions are no longer allowed, set flag to false. // This transaction has been completed. Zombie(); } else { ZombieParent(); } } catch (Exception e) { // UNDONE - should not be catching all exceptions!!! if (ADP.IsCatchableExceptionType(e)) { CheckTransactionLevelAndZombie(); } throw; } } }
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Save/*' /> public void Save(string savePointName) { ZombieCheck(); SqlStatistics statistics = null; using (TryEventScope.Create("SqlTransaction.Save | API | Object Id {0} | Save Point Name '{1}'", ObjectID, savePointName)) { try { statistics = SqlStatistics.StartTimer(Statistics); _internalTransaction.Save(savePointName); } finally { SqlStatistics.StopTimer(statistics); } } }
internal int ExecuteNonQuery() { SqlConnection.ExecutePermission.Demand(); using (TryEventScope.Create("<sc.SqlCommandSet.ExecuteNonQuery|API> {0}", ObjectID)) { if (Connection.IsContextConnection) { throw SQL.BatchedUpdatesNotAvailableOnContextConnection(); } ValidateCommandBehavior(ADP.ExecuteNonQuery, CommandBehavior.Default); BatchCommand.BatchRPCMode = true; BatchCommand.ClearBatchCommand(); BatchCommand.Parameters.Clear(); for (int ii = 0; ii < _commandList.Count; ii++) { LocalCommand cmd = _commandList[ii]; BatchCommand.AddBatchCommand(cmd.CommandText, cmd.Parameters, cmd.CmdType, cmd.ColumnEncryptionSetting); } return(BatchCommand.ExecuteBatchRPCCommand()); } }
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Rollback2/*' /> override public void Rollback() { using (DiagnosticTransactionScope diagnosticScope = s_diagnosticListener.CreateTransactionRollbackScope(_isolationLevel, _connection, InternalTransaction, null)) { if (Is2005PartialZombie) { // Put something in the trace in case a customer has an issue SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Rollback | ADV | Object Id {0}, partial zombie no rollback required", ObjectID); _internalTransaction = null; // 2005 zombification } else { ZombieCheck(); SqlStatistics statistics = null; using (TryEventScope.Create("SqlTransaction.Rollback | API | Object Id {0}", ObjectID)) { SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlTransaction.Rollback | API | Correlation | Object Id {0}, ActivityID {1}, Client Connection Id {2}", ObjectID, ActivityCorrelator.Current, Connection?.ClientConnectionId); try { statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Rollback(); } catch (Exception ex) { diagnosticScope.SetException(ex); throw; } finally { SqlStatistics.StopTimer(statistics); _isFromAPI = false; } } } } }
internal void Rollback() { using (TryEventScope.Create("<sc.SqlInternalTransaction.Rollback|API> {0}", ObjectID)) { if (_innerConnection.IsLockedForBulkCopy) { throw SQL.ConnectionLockedForBcpEvent(); } _innerConnection.ValidateConnectionForExecute(null); try { // If no arg is given to ROLLBACK it will rollback to the outermost begin - rolling back // all nested transactions as well as the outermost transaction. _innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.IfRollback, null, IsolationLevel.Unspecified, null, false); // Since Rollback will rollback to outermost begin, no need to check // server transaction level. This transaction has been completed. Zombie(); } catch (Exception e) { // UNDONE - should not be catching all exceptions!!! if (ADP.IsCatchableExceptionType(e)) { CheckTransactionLevelAndZombie(); if (!_disposing) { throw; } } else { throw; } } } }
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/RollbackTransactionName/*' /> public void Rollback(string transactionName) { Exception e = null; Guid operationId = s_diagnosticListener.WriteTransactionRollbackBefore(_isolationLevel, _connection, InternalTransaction, transactionName); ZombieCheck(); using (TryEventScope.Create(SqlClientEventSource.Log.TryScopeEnterEvent("SqlTransaction.Rollback | API | Object Id {0}, Transaction Name='{1}', ActivityID {2}, Client Connection Id {3}", ObjectID, transactionName, ActivityCorrelator.Current, Connection?.ClientConnectionId))) { SqlStatistics statistics = null; try { statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Rollback(transactionName); } catch (Exception ex) { e = ex; throw; } finally { SqlStatistics.StopTimer(statistics); if (e != null) { s_diagnosticListener.WriteTransactionRollbackError(operationId, _isolationLevel, _connection, InternalTransaction, e, transactionName); } else { s_diagnosticListener.WriteTransactionRollbackAfter(operationId, _isolationLevel, _connection, InternalTransaction, transactionName); } _isFromAPI = false; } } }
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlFileStream.xml' path='docs/members[@name="SqlFileStream"]/ctor2/*' /> public SqlFileStream ( string path, byte[] transactionContext, System.IO.FileAccess access, System.IO.FileOptions options, Int64 allocationSize ) { using (TryEventScope.Create(SqlClientEventSource.Log.TryScopeEnterEvent("<sc.SqlFileStream.ctor|API> {0} access={1} options={2} path='{3}'", ObjectID, (int)access, (int)options, path))) { //----------------------------------------------------------------- // precondition validation if (transactionContext == null) { throw ADP.ArgumentNull("transactionContext"); } if (path == null) { throw ADP.ArgumentNull("path"); } //----------------------------------------------------------------- m_disposed = false; m_fs = null; OpenSqlFileStream(path, transactionContext, access, options, allocationSize); // only set internal state once the file has actually been successfully opened this.Name = path; this.TransactionContext = transactionContext; } }
//////////////////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS //////////////////////////////////////////////////////////////////////////////////////// /// <include file='..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Commit/*' /> override public void Commit() { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; using (TryEventScope.Create("<sc.SqlTransaction.Commit|API> {0}", ObjectID)) { SqlClientEventSource.Log.TryCorrelationTraceEvent("<sc.SqlTransaction.Commit|API|Correlation> ObjectID {0}, ActivityID {1}", ObjectID, ActivityCorrelator.Current); 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; } catch (SqlException e) { // GitHub Issue #130 - When a timeout exception has occurred on transaction completion request, // this connection may not be in reusable state. // We will abort this connection and make sure it does not go back to the pool. var innerException = e.InnerException as Win32Exception; if (innerException != null && innerException.NativeErrorCode == TdsEnums.SNI_WAIT_TIMEOUT) { _connection.Abort(e); } throw; } finally { _isFromAPI = false; SqlStatistics.StopTimer(statistics); } } }
/// <include file='..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Rollback2/*' /> override public void Rollback() { if (Is2005PartialZombie) { // Put something in the trace in case a customer has an issue SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlTransaction.Rollback|ADV> {0} partial zombie no rollback required", ObjectID); _internalTransaction = null; // 2005 zombification } else { ZombieCheck(); SqlStatistics statistics = null; using (TryEventScope.Create("<sc.SqlTransaction.Rollback|API> {0}", ObjectID)) { SqlClientEventSource.Log.TryCorrelationTraceEvent("<sc.SqlTransaction.Rollback|API|Correlation> ObjectID {0}, ActivityID {1}", ObjectID, ActivityCorrelator.Current); 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); } } } }