首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在处理SqlTransaction之前检查状态

如何在处理SqlTransaction之前检查状态
EN

Stack Overflow用户
提问于 2013-01-21 12:35:28
回答 4查看 13.1K关注 0票数 4

下面的代码使用SqlTransaction。我叫了dispose in catch,最后阻止了..但是,在调用Dispose()之前,我还没有检查它是否已经被释放。如何在调用Dispose()之前检查SqlTransaction是否已被释放?

我已经提到MSDN:SqlTransaction.Dispose法了。但这不包括我的问题。

还提到了http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.dispose(v=vs.100).aspx

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

代码语言:javascript
复制
 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();
                }
            }
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-01-21 12:42:35

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

你不需要这么做。打两次电话不会给你带来任何问题。

Dispose - MSDN

如果一个对象的Dispose方法被多次调用,则该对象必须忽略第一个调用之后的所有调用。如果多次调用对象的Dispose方法,则该对象不能抛出异常。当资源已被释放时,除Dispose之外的实例方法可以抛出ObjectDisposedException。

但是,如果您只想调用Dispose一次,那么您可以使用布尔标志来设置事务处理时的设置,也可以将其设置为null。或者删除要在catch块中释放的调用,因为finally块将始终被调用。

由于SqlTransaction实现了IDisposable,所以如果您在使用块时使用它,会更好。类似于:

代码语言:javascript
复制
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;
        }
    }
}

因为使用块类似于try/finally块,因此它将确保事务完成后进行处理(即使出现异常)。因此,您不必手动调用Dispose

票数 8
EN

Stack Overflow用户

发布于 2013-01-21 12:38:33

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

票数 2
EN

Stack Overflow用户

发布于 2013-01-21 12:40:36

你为什么要检查它是否已经处理好了?只需从Dispose块中省略调用,就可以避免两次调用catch

代码语言:javascript
复制
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();
        }
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14438736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档