【发布时间】:2019-10-25 15:48:47
【问题描述】:
在存储过程中,我有一个带有事务的 try catch 块,如果控制永远不会传递给 catch,它将提交,否则如果出现错误并且控制确实传递给 catch 块,则会回滚。
我正在事务中运行此存储过程,如下例所示:
CREATE PROCEDURE sp_test
AS
BEGIN
BEGIN TRY
BEGIN TRAN
DECLARE @var INT = 1
IF @var <> 2
BEGIN
RAISERROR('error', 16,1)
END
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
PRINT 'Rolled back'
END CATCH
END
BEGIN TRAN
EXEC sp_test
当我运行它时,我看到了错误
消息 266,级别 16,状态 2,过程 sp_test,第 0 行 [批处理开始第 7 行]
EXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 1,当前计数 = 0。
但我不明白为什么。
我正在存储过程之外开始一个事务。然后我将进入 SP 并开始另一笔交易。一旦控制传递到 catch 块,两个事务都应该回滚,所以事务计数应该是 0。
显然这里我的理解有差距。
【问题讨论】:
-
旁注:您应该不为您的存储过程使用
sp_前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免sp_并使用其他东西作为前缀 - 或者根本不使用前缀! -
EXEC sp_test之后的COMMIT在哪里?此外,在使用事务的 SP 之外使用事务是没有意义的。 SQL Server 中没有嵌套事务之类的东西。 A SQL Server DBA myth a day: (26/30) nested transactions are real
标签: sql-server stored-procedures transactions try-catch