首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我需要捕获回滚异常吗?

我需要捕获回滚异常吗?
EN

Stack Overflow用户
提问于 2014-10-24 16:20:33
回答 1查看 1.6K关注 0票数 2

如何在RollBack上捕获异常相关但不相同

如果我们捕获并显式回滚,我们似乎需要尝试/捕获包装回滚调用。彻底消除try/catch是否仍然是回滚,如果回滚失败,仍然会发送根原因异常而不是回滚异常吗?我已经尝试过如何复制这个,但是我不知道如何强制回滚超时。

这是遗留模式:

代码语言:javascript
复制
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
    conn.Open();
    using (SqlTransaction trans = conn.BeginTransaction())
    {
        try
        {
            //do stuff
            trans.Commit();
        }
        catch
        {
            trans.Rollback();
            throw;
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-24 16:39:34

这是我在整个职业生涯中使用和看到的一种模式。最近,我遇到了一种情况,在生产中出现异常,堆栈跟踪显示回滚超时,而不是实际发生的异常。从我的分析中可以看出,更好的做法是不要在捕获中使用显式Rollback,而是让using语句来处理它。

这允许正确的根原因异常冒泡,事务将在服务器上回滚。为了复制Rollback超时,我创建了一个表和一个过程,并从单元测试中调用事务中的存储过程。

代码语言:javascript
复制
    /****** Object:  Table [dbo].[Table_1]    Script Date: 10/24/2014 12:07:42 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Table_1](
    [id] [int] NULL,
    [GuidTest] [uniqueidentifier] NULL,
    [GuidTest2] [uniqueidentifier] NULL,
    [GuidTest3] [uniqueidentifier] NULL
) ON [PRIMARY]





  /****** Object:  StoredProcedure [dbo].[Test_RollBack]    Script Date: 10/24/2014 12:08:04 PM ******/

/****** Object:  StoredProcedure [dbo].[Test_RollBack]    Script Date: 10/24/2014 12:08:04 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


CREATE PROCEDURE [dbo].[Test_RollBack]  
AS
BEGIN
    DECLARE @counter int = 1

    while @counter < 3000000
    BEGIN
        INSERT INTO Table_1(id, GuidTest, GuidTest2, GuidTest3)
        VALUES(@counter, newId(), newId(), newId())
        set @counter = @counter + 1
    END


    update Table_1
    SET GuidTest = newid()
END

GO


[TestMethod()]
    public void RollBackTestTimeout()
    {
        using (SqlConnection conn = new SqlConnection("Your ConnectionString"))
        {
            conn.Open();

            using (SqlTransaction trans = conn.BeginTransaction())
            {
                using (SqlCommand cmd = new SqlCommand())
                {
                    try
                    {

                        cmd.Connection = conn;
                        cmd.Transaction = trans;
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.CommandText = "Test_RollBack";

                        cmd.ExecuteNonQuery();

                        trans.Commit();
                    }
                    catch
                    {
                        trans.Rollback();

                        throw;
                    }
                }
            }

        }
    }

    [TestMethod()]
    public void RollBackTestTimeout_WithUsing()
    {
        using (SqlConnection conn = new SqlConnection("Your ConnectionString"))
        {
            conn.Open();

            using (SqlTransaction trans = conn.BeginTransaction())
            {
                using (SqlCommand cmd = new SqlCommand())
                {
                    cmd.Connection = conn;
                    cmd.Transaction = trans;
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = "Test_RollBack";

                    cmd.ExecuteNonQuery();

                    trans.Commit();
                }
            }

        }
    }

对我来说,RollBackTestTimeout测试方法抛出一个SqlCommandTimeout,但是报告回滚超时,RollBackTestTimeout_WithUsing实际上显示了根本原因异常。因此,根据我所发现的,我会说,让使用句柄,以便您可以调试您的问题在生产以后。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26552079

复制
相关文章

相似问题

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