49

如果我在 SQL 中创建一个存储过程并EXEC spStoredProcedure在 BEGIN/END TRANSACTION 中调用它(),那么这个其他存储过程是否也属于该事务?

我不知道它是否像 C# 中的 try/catch 一样工作。

4

7 回答 7

50

是的,您在开始事务和提交(或回滚)之间所做的一切都是事务的一部分。

于 2008-10-07T20:11:08.053 回答
14

听起来不错,非常感谢。我最终做了这样的事情(因为我在 05)

    BEGIN TRY
       BEGIN TRANSACTION

       DO SOMETHING

       COMMIT
    END TRY
    BEGIN CATCH
      IF @@TRANCOUNT > 0
         ROLLBACK

      -- Raise an error with the details of the exception
      DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int
      SELECT @ErrMsg = ERROR_MESSAGE(),
             @ErrSeverity = ERROR_SEVERITY()

      RAISERROR(@ErrMsg, @ErrSeverity, 1)
    END CATCH
于 2008-10-07T20:16:45.797 回答
6

我相信在 MS SQL Server 中,存储过程的执行会在事务中发生,但要非常小心。如果您有嵌套事务(即,存储过程之外的事务和存储过程内部的不同事务),回滚将影响所有事务,而不仅仅是最近的封闭事务。

于 2008-10-07T20:11:58.207 回答
6

正如 Chris 所提到的,您应该小心回滚事务。

具体来说:

IF @@TRANCOUNT > 0 ROLLBACK

并不总是你想要的。你可以做这样的事情

IF(@@TRANCOUNT = 1) ROLLBACK TRAN
ELSE IF(@@TRANCOUNT > 1) COMMIT TRAN
RETURN @error

这样,调用 proc 可以检查存储过程的返回值,并确定它是要提交还是继续冒泡错误。

原因是“提交”只会减少您的交易计数器。一旦它将事务计数器减为零,就会发生实际的提交。

于 2008-10-07T20:42:08.863 回答
3

正如ChrisJames所提到的,在处理嵌套事务时需要小心。Don PetersonSQL Server Central上写了一组非常好的关于事务主题的文章,我建议您阅读这些文章:

这里有:

于 2008-10-08T08:57:57.117 回答
1

是的,所有嵌套的存储过程调用都包含在事务的范围内。如果您使用的是 SQL Server 2005 或更高版本,您也可以使用 Try...Catch。 这里有更多细节。

于 2008-10-07T20:14:53.163 回答
1

@Chris,我不知道。

当谷歌搜索更多信息时,我遇到了这个- 你可以设置“保存点”,可以回滚而不回滚整个事务。

在这种情况下可能有用。

于 2008-10-07T22:23:14.247 回答