回滚而不抛出异常?

Posted

技术标签:

【中文标题】回滚而不抛出异常?【英文标题】:Rollback without throwing an exception? 【发布时间】:2013-10-02 18:48:04 【问题描述】:

在 SQL Server 2008r2 上,我们有一个如下所示的存储过程:

create procedure x(@arg1 as nvarchar(20), @arg2 ... )
as
begin
  -- delete and insert values, depending on arguments
   begin transaction;
   delete from tblA where f1 = @arg1 ... ; 
   insert into tblB (a) select ... where f2 = @arg2 ... ; 
   commit transaction;
end;

我在 C# (.NET 4.5) 中使用 SqlCommand.ExecuteNonQuery() 方法调用此过程。 所有异常都被try--- catch捕获

现在在此方法的文档中,它说 “如果发生回滚,则返回值为 -1。”

问题:是否会发生回滚而没有异常?

到目前为止,我们总是遇到异常,如果 sql 语句无法执行。但是是否会出现回滚“自动”发生而不抛出异常的情况?

【问题讨论】:

hummm - 我认为根据 XACT_ABORT 设置,您可能会进入一个状态,即删除被尊重但插入不是。 @MikeMiller 在这种情况下,程序会简单地回滚,而不是抛出异常? 如果设置不正确,进程会抛出异常,只回滚Insert。 【参考方案1】:

你能看一下gbn的答案,交易模板吗 Nested stored procedures containing TRY CATCH ROLLBACK pattern?

根据你的问题,我已经修改了回滚时返回-1的过程。

CREATE PROCEDURE [Name]
    @arg1 as nvarchar(20), 
    @arg2 as nvarchar(20)
AS
    SET XACT_ABORT, NOCOUNT ON

    DECLARE @starttrancount int

    BEGIN TRY
        SELECT @starttrancount = @@TRANCOUNT

        IF @starttrancount = 0
            BEGIN TRANSACTION

         delete from tblA where f1 = @arg1 ... ; 
         insert into tblB (a) select ... where f2 = @arg2 ... ; 

        IF @starttrancount = 0 
            COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        IF XACT_STATE() <> 0 AND @starttrancount = 0 
        BEGIN
           ROLLBACK TRANSACTION
           RETURN -1
        END  
    END CATCH
    GO

【讨论】:

可能有误会。我想保持我的程序不变。我用 ExecuteNonQuery() 调用它。我只是想知道,如果在这个星座中它可能发生,那么 ExecuteNonQuery() 将返回 -1 而不会引发异常。 是的,我希望如此。因为如果没有行受到影响,它将返回-1。对于 UPDATE、INSERT 和 DELETE 语句,返回值是受命令影响的行数。当正在插入或更新的表上存在触发器时,返回值包括受插入或更新操作影响的行数以及受一个或多个触发器影响的行数。对于所有其他类型的语句,返回值为 -1。如果发生回滚,则返回值也是 -1。来源:msdn.microsoft.com/en-us/library/… 我认为这两个链接会有所帮助***.com/questions/10784830/…***.com/questions/1833539/…

以上是关于回滚而不抛出异常?的主要内容,如果未能解决你的问题,请参考以下文章

Spring事务异常回滚,捕获异常不抛出就不会回滚

Spring事务异常回滚,捕获异常不抛出就不会回滚

Spring事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题

UserManager 退出函数而不抛出任何异常

HttpClient.SendAsync 方法退出而不抛出异常

如何从子方法中退出方法而不抛出异常