【问题标题】:How to check state before disposing SqlTransaction如何在处理 SqlTransaction 之前检查状态
【发布时间】:2013-01-21 12:35:28
【问题描述】:

我有以下使用 SqlTransaction 的代码。我已经在 catch 中调用了 dispose 并最终阻塞了。但是在调用 Dispose() 之前我没有检查它是否已经被释放。我们如何在调用 Dispose() 之前检查 SqlTransaction 是否已经被释放?

我已经推荐了MSDN:SqlTransaction.Dispose Method。但这不包括我的问题。

也称为http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.dispose(v=vs.100).aspx

注意:我已经知道TransactionScopeSqlTransaction 有优势。但我试图了解 SqlTransaction 的处置。

代码

 using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();

            SqlTransaction transaction = null;

            try
            {
                transaction = connection.BeginTransaction();

                sessionID = GetSessionIDForAssociate(connection, empID, transaction);
                //Other code

                //Commit
                transaction.Commit();
            }
            catch
            {
                //Rollback
                if (transaction != null)
                {
                    transaction.Rollback();
                    transaction.Dispose();
                }

                //Throw exception
                throw;
            }
            finally
            {
                if (transaction != null)
                {
                    transaction.Dispose();
                }
            }

【问题讨论】:

    标签: c# .net ado.net


    【解决方案1】:

    我们如何检查 SqlTransaction 之前是否已经被释放 调用 Dispose()?

    您不必这样做。调用 dispose 两次不会给您带来任何问题。

    Dispose - MSDN

    如果一个对象的 Dispose 方法被多次调用,该对象 必须忽略第一个呼叫之后的所有呼叫。物体不得抛出 如果多次调用其 Dispose 方法,则会出现异常。实例 Dispose 以外的方法在以下情况下可能会引发 ObjectDisposedException 资源已被释放。

    但是,如果您只想调用一次 Dispose,那么您可以使用布尔标志来设置事务何时被处理,或者您可以将其设置为 null。或者删除 catch 块中对 dispose 的调用,因为总是会调用 finally 块。

    由于 SqlTransaction 实现了IDisposable如果将它与 using 块一起使用会更好。比如:

    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
    
        using (SqlTransaction transaction = connection.BeginTransaction())
        {
            try
            {
                sessionID = GetSessionIDForAssociate(connection, empID, transaction);
                //Other code
    
                //Commit
                transaction.Commit();
            }
            catch
            {
                //Rollback
                if (transaction != null)
                {
                    transaction.Rollback();
                }
    
                //Throw exception
                throw;
            }
        }
    }
    

    由于 using 块的行为类似于try/finally 块,它会确保在事务完成后处理事务(即使发生异常)。这样您就不必手动调用Dispose

    【讨论】:

      【解决方案2】:

      在你调用 dispose 后添加transaction=null,然后你现有的测试就可以工作了。

      【讨论】:

        【解决方案3】:

        为什么要检查它是否已被处置?您可以通过简单地省略 catch 块中的调用来避免调用 Dispose 两次:

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
        
            SqlTransaction transaction = null;
        
            try
            {
                transaction = connection.BeginTransaction();
        
                sessionID = GetSessionIDForAssociate(connection, empID, transaction);
                //Other code
        
                //Commit
                transaction.Commit();
            }
            catch
            {
                //Rollback
                if (transaction != null)
                {
                    // No need to dispose here - finally is always called
                    transaction.Rollback();
                }
        
                //Throw exception
                throw;
            }
            finally
            {
                if (transaction != null)
                {
                    // Always called, so no need to dispose elsewhere.
                    transaction.Dispose();
                }
            }
        

        【讨论】:

          【解决方案4】:

          从 catch 块中删除 .Dispose() 调用。 finally 总是被执行,所以这样你会尝试两次来处理事务。

          它没有回答“我怎么知道它是否已经被处理”但可能会解决你的问题。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-17
            • 1970-01-01
            • 2021-12-17
            • 1970-01-01
            相关资源
            最近更新 更多