コード例 #1
0
        internal void AutomaticEnlistment()
        {
            SysTx.Transaction currentSystemTransaction = ADP.GetCurrentTransaction();    // NOTE: Must be first to ensure _smiContext.ContextTransaction is set!
            SysTx.Transaction contextTransaction       = _smiContext.ContextTransaction; // returns the transaction that was handed to SysTx that wraps the ContextTransactionId.
            long contextTransactionId = _smiContext.ContextTransactionId;

            if (Bid.AdvancedOn)
            {
                Bid.Trace("<sc.SqlInternalConnectionSmi.AutomaticEnlistment|ADV> %d#, contextTransactionId=0x%I64x, contextTransaction=%d#, currentSystemTransaction=%d#.\n",
                          base.ObjectID,
                          contextTransactionId,
                          (null != contextTransaction) ? contextTransaction.GetHashCode() : 0,
                          (null != currentSystemTransaction) ? currentSystemTransaction.GetHashCode() : 0);
            }

            if (SqlInternalTransaction.NullTransactionId != contextTransactionId)
            {
                if (null != currentSystemTransaction && contextTransaction != currentSystemTransaction)
                {
                    throw SQL.NestedTransactionScopesNotSupported();    // can't use TransactionScope(RequiresNew) inside a Sql Transaction.
                }
                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.SqlInternalConnectionSmi.AutomaticEnlistment|ADV> %d#, using context transaction with transactionId=0x%I64x\n", base.ObjectID, contextTransactionId);
                }
                _currentTransaction = new SqlInternalTransaction(this, TransactionType.Context, null, contextTransactionId);
                ContextTransaction  = contextTransaction;
            }
            else if (null == currentSystemTransaction)
            {
                _currentTransaction = null;  // there really isn't a transaction.

                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.SqlInternalConnectionSmi.AutomaticEnlistment|ADV> %d#, no transaction.\n", base.ObjectID);
                }
            }
            else
            {
                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.SqlInternalConnectionSmi.AutomaticEnlistment|ADV> %d#, using current System.Transaction.\n", base.ObjectID);
                }
                base.Enlist(currentSystemTransaction);
            }
        }
コード例 #2
0
ファイル: SqlTransaction.cs プロジェクト: yesmey/SqlClient
        internal SqlTransaction(SqlInternalConnection internalConnection, SqlConnection con,
                                IsolationLevel iso, SqlInternalTransaction internalTransaction)
        {
            _isolationLevel = iso;
            _connection     = con;

            if (internalTransaction == null)
            {
                _internalTransaction = new SqlInternalTransaction(internalConnection, TransactionType.LocalFromAPI, this);
            }
            else
            {
                Debug.Assert(internalConnection.CurrentTransaction == internalTransaction, "Unexpected Parser.CurrentTransaction state!");
                _internalTransaction = internalTransaction;
                _internalTransaction.InitParent(this);
            }
        }
コード例 #3
0
ファイル: SqlTransaction.cs プロジェクト: ulvii/SqlClient
        ////////////////////////////////////////////////////////////////////////////////////////
        // INTERNAL METHODS
        ////////////////////////////////////////////////////////////////////////////////////////

        internal void Zombie()
        {
            // SQLBUDT #402544 For Yukon, we have to defer "zombification" until
            //                 we get past the users' next rollback, else we'll
            //                 throw an exception there that is a breaking change.
            //                 Of course, if the connection is aready closed,
            //                 then we're free to zombify...
            SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection);

            if (null != internalConnection && internalConnection.IsYukonOrNewer && !_isFromAPI)
            {
                SqlClientEventSource.Log.AdvanceTrace("<sc.SqlTransaction.Zombie|ADV> {0}# yukon deferred zombie", ObjectID);
            }
            else
            {
                _internalTransaction = null; // pre-yukon zombification
            }
        }
コード例 #4
0
        ////////////////////////////////////////////////////////////////////////////////////////
        // INTERNAL METHODS
        ////////////////////////////////////////////////////////////////////////////////////////

        internal void Zombie()
        {
            // For 2005, we have to defer "zombification" until
            //                 we get past the users' next rollback, else we'll
            //                 throw an exception there that is a breaking change.
            //                 Of course, if the connection is already closed,
            //                 then we're free to zombify...
            SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection);

            if (null != internalConnection && !_isFromAPI)
            {
                SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Zombie | ADV | Object Id {0} 2005 deferred zombie", ObjectID);
            }
            else
            {
                _internalTransaction = null; // pre-2005 zombification
            }
        }
コード例 #5
0
        private void TransactionEnded(long transactionId, TransactionState transactionState)
        {
            // When we get notification of a completed transaction
            // we null out the current transaction.

            if (null != _currentTransaction)
            {
#if DEBUG
                // Check null for case where Begin and Rollback obtained in the same message.
                if (0 != _currentTransaction.TransactionId)
                {
                    Debug.Assert(_currentTransaction.TransactionId == transactionId, "transaction id's are not equal!");
                }
#endif
                _currentTransaction.Completed(transactionState);
                _currentTransaction = null;
            }
        }
コード例 #6
0
        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;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                if (connection.IsEnlistedInTransaction)
                { // defect first
                    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;
            }
            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;
            }
        }
コード例 #7
0
ファイル: SqlTransaction.cs プロジェクト: ulvii/SqlClient
        /// <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, null);

            if (IsYukonPartialZombie)
            {
                // Put something in the trace in case a customer has an issue
                _internalTransaction = null; // yukon zombification
            }
            else
            {
                ZombieCheck();

                SqlStatistics statistics = null;
                try
                {
                    statistics = SqlStatistics.StartTimer(Statistics);

                    _isFromAPI = true;

                    _internalTransaction.Rollback();
                }
                catch (Exception ex)
                {
                    e = ex;
                    throw;
                }
                finally
                {
                    if (e != null)
                    {
                        s_diagnosticListener.WriteTransactionRollbackError(operationId, _isolationLevel, _connection, null, e);
                    }
                    else
                    {
                        s_diagnosticListener.WriteTransactionRollbackAfter(operationId, _isolationLevel, _connection, null);
                    }
                    _isFromAPI = false;

                    SqlStatistics.StopTimer(statistics);
                }
            }
        }
コード例 #8
0
        /// <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 (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)
                        {
                            diagnosticScope.SetException(ex);
                            throw;
                        }
                        finally
                        {
                            SqlStatistics.StopTimer(statistics);
                            _isFromAPI = false;
                        }
                    }
                }
            }
        }
コード例 #9
0
        private void TransactionStarted(long transactionId, bool isDistributed)
        {
            // When we get notification from the server of a new
            // transaction, we move any pending transaction over to
            // the current transaction, then we store the token in it.
            // if there isn't a pending transaction, then it's either
            // a TSQL transaction or a distributed transaction.
            Debug.Assert(null == _currentTransaction, "non-null current transaction with an env change");
            _currentTransaction = _pendingTransaction;
            _pendingTransaction = null;

            if (null != _currentTransaction)
            {
                _currentTransaction.TransactionId = transactionId;   // this is defined as a ULongLong in the server and in the TDS Spec.
            }
            else
            {
                TransactionType transactionType = (isDistributed) ? TransactionType.Distributed : TransactionType.LocalFromTSQL;
                _currentTransaction = new SqlInternalTransaction(this, transactionType, null, transactionId);
            }
            _currentTransaction.Activate(); // SQLBUDT #376531 -- ensure this is activated to prevent asserts later.
        }
        public static DiagnosticTransactionScope CreateTransactionRollbackScope(SqlDiagnosticListener diagnostics, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName, [CallerMemberName] string operationName = "")
        {
            Guid operationId = diagnostics.WriteTransactionRollbackBefore(isolationLevel, connection, transaction, transactionName, operationName);

            return(new DiagnosticTransactionScope(diagnostics, TransactionCommit, operationId, operationName, isolationLevel, connection, transaction, transactionName));
        }
 public static DiagnosticTransactionScope CreateTransactionRollbackScope(this SqlDiagnosticListener @this, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName, [CallerMemberName] string operationName = "")
 {
     return(DiagnosticTransactionScope.CreateTransactionRollbackScope(@this, isolationLevel, connection, transaction, transactionName, operationName));
 }
コード例 #12
0
 public static void WriteTransactionCommitAfter(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operation = "")
 {
     if (@this.IsEnabled(SqlAfterCommitTransaction))
     {
         @this.Write(
             SqlAfterCommitTransaction,
             new
         {
             OperationId    = operationId,
             Operation      = operation,
             IsolationLevel = isolationLevel,
             Connection     = connection,
             transaction?.TransactionId,
             Timestamp = Stopwatch.GetTimestamp()
         });
     }
 }
コード例 #13
0
 override internal void DelegatedTransactionEnded()
 {
     base.DelegatedTransactionEnded();
     SqlClientEventSource.Log.AdvanceTrace("<sc.SqlInternalConnectionSmi.DelegatedTransactionEnded|ADV> {0}#, cleaning up after Delegated Transaction Completion", ObjectID);
     _currentTransaction = null;           // clean up our current transaction too
 }
コード例 #14
0
        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;
            }
        }
コード例 #15
0
ファイル: SqlTransaction.cs プロジェクト: ulvii/SqlClient
        /// <include file='..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Rollback2/*' />
        override public void Rollback()
        {
            if (IsYukonPartialZombie)
            {
                // Put something in the trace in case a customer has an issue
                SqlClientEventSource.Log.AdvanceTrace("<sc.SqlTransaction.Rollback|ADV> {0}# partial zombie no rollback required", ObjectID);

                _internalTransaction = null; // yukon zombification
            }
            else
            {
                ZombieCheck();

                SqlStatistics statistics = null;
                long          scopeID    = SqlClientEventSource.Log.ScopeEnterEvent("<sc.SqlTransaction.Rollback|API> {0}#", ObjectID);
                SqlClientEventSource.Log.CorrelationTraceEvent("<sc.SqlTransaction.Rollback|API|Correlation> ObjectID {0}#, ActivityID {1}", ObjectID, ActivityCorrelator.Current.ToString());

                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);
                    SqlClientEventSource.Log.ScopeLeaveEvent(scopeID);
                }
            }
        }
コード例 #16
0
 abstract internal void DisconnectTransaction(SqlInternalTransaction internalTransaction);
コード例 #17
0
 abstract internal void ExecuteTransaction(TransactionRequest transactionRequest, string name, IsolationLevel iso, SqlInternalTransaction internalTransaction, bool isDelegateControlRequest);
コード例 #18
0
        public static Guid WriteTransactionRollbackBefore(this SqlDiagnosticListener @this, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName = null, [CallerMemberName] string operation = "")
        {
            if (@this.IsEnabled(SqlBeforeRollbackTransaction))
            {
                Guid operationId = Guid.NewGuid();

                @this.Write(
                    SqlBeforeRollbackTransaction,
                    new
                {
                    OperationId    = operationId,
                    Operation      = operation,
                    IsolationLevel = isolationLevel,
                    Connection     = connection,
                    transaction?.TransactionId,
                    TransactionName = transactionName,
                    Timestamp       = Stopwatch.GetTimestamp()
                });

                return(operationId);
            }
            else
            {
                return(Guid.Empty);
            }
        }
コード例 #19
0
 public static void WriteTransactionRollbackError(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, Exception ex, string transactionName = null, [CallerMemberName] string operation = "")
 {
     if (@this.IsEnabled(SqlErrorRollbackTransaction))
     {
         @this.Write(
             SqlErrorRollbackTransaction,
             new
         {
             OperationId    = operationId,
             Operation      = operation,
             IsolationLevel = isolationLevel,
             Connection     = connection,
             transaction?.TransactionId,
             TransactionName = transactionName,
             Exception       = ex,
             Timestamp       = Stopwatch.GetTimestamp()
         });
     }
 }
 public DiagnosticTransactionScope(SqlDiagnosticListener diagnostics, int operation, Guid operationId, string operationName, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName)
 {
     _diagnostics     = diagnostics;
     _operation       = operation;
     _operationId     = operationId;
     _operationName   = operationName;
     _isolationLevel  = isolationLevel;
     _connection      = connection;
     _transaction     = transaction;
     _transactionName = transactionName;
     _exception       = null;
 }
コード例 #21
0
        /// <include file='..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlTransaction.xml' path='docs/members[@name="SqlTransaction"]/Rollback2/*' />
        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);
                }
            }
        }
コード例 #22
0
        override internal void ExecuteTransaction(
            TransactionRequest transactionRequest,
            string transactionName,
            IsolationLevel iso,
            SqlInternalTransaction internalTransaction,
            bool isDelegateControlRequest)
        {
            if (Bid.AdvancedOn)
            {
                Bid.Trace("<sc.SqlInternalConnectionSmi.ExecuteTransaction|ADV> %d#, transactionRequest=%ls, transactionName='%ls', isolationLevel=%ls, internalTransaction=#%d transactionId=0x%I64x.\n",
                          base.ObjectID,
                          transactionRequest.ToString(),
                          (null != transactionName) ? transactionName : "null",
                          iso.ToString(),
                          (null != internalTransaction) ? internalTransaction.ObjectID : 0,
                          (null != internalTransaction) ? internalTransaction.TransactionId : SqlInternalTransaction.NullTransactionId
                          );
            }
            switch (transactionRequest)
            {
            case TransactionRequest.Begin:
                try
                {
                    _pendingTransaction = internalTransaction;     // store this for the time being.

                    _smiConnection.BeginTransaction(transactionName, iso, _smiEventSink);
                }
                finally
                {
                    _pendingTransaction = null;
                }

                Debug.Assert(_smiEventSink.HasMessages || null != _currentTransaction, "begin transaction without TransactionStarted event?");
                break;

            case TransactionRequest.Commit:
                Debug.Assert(null != _currentTransaction, "commit transaction without TransactionStarted event?");

                _smiConnection.CommitTransaction(_currentTransaction.TransactionId, _smiEventSink);
                break;

            case TransactionRequest.Promote:
                Debug.Assert(null != _currentTransaction, "promote transaction without TransactionStarted event?");
                PromotedDTCToken = _smiConnection.PromoteTransaction(_currentTransaction.TransactionId, _smiEventSink);
                break;

            case TransactionRequest.Rollback:
            case TransactionRequest.IfRollback:
                Debug.Assert(null != _currentTransaction, "rollback/ifrollback transaction without TransactionStarted event?");
                _smiConnection.RollbackTransaction(_currentTransaction.TransactionId, transactionName, _smiEventSink);
                break;

            case TransactionRequest.Save:
                Debug.Assert(null != _currentTransaction, "save transaction without TransactionStarted event?");
                _smiConnection.CreateTransactionSavePoint(_currentTransaction.TransactionId, transactionName, _smiEventSink);
                break;

            default:
                Debug.Assert(false, "unhandled case for TransactionRequest");
                break;
            }

            _smiEventSink.ProcessMessagesAndThrow();
        }