【发布时间】:2017-10-11 09:28:41
【问题描述】:
我按照推荐的模板来处理事务中的错误,该模板在现有事务中执行时应该可以工作。
这是我的模板
CREATE PROCEDURE DoSomething
AS
BEGIN
SET NOCOUNT ON
DECLARE @trans INTEGER = @@TRANCOUNT
IF (@trans > 0)
SAVE TRANSACTION SavePoint
ELSE
BEGIN TRANSACTION
BEGIN TRY
-- code with a check that does a THROW if the requirements aren't met
IF (@trans = 0)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF (@trans > 0)
ROLLBACK TRANSACTION SavePoint
ELSE
ROLLBACK TRANSACTION
;THROW
END CATCH
END
如果我将 TRY 块中的 THROW 替换为 RAISERROR,问题仍然存在。
测试结果:
事务中的执行失败场景:正确的结果(给出正确的错误消息)
事务中的 EXEC 成功场景: 出现意外错误。
EXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 1,当前计数 = 2。
事务外的执行失败场景:给出预期错误。
事务外的 EXEC 成功场景: 出现意外错误。错误和上面一样,但是每次执行它都会增加-1。这是否意味着每次都会有更多的东西未被提交?
这是一个测试的样子:
BEGIN TRANSACTION
EXEC ...
ROLLBACK TRANSACTION
有人知道怎么回事吗?
【问题讨论】:
-
IMPLICIT_TRANSACTIONS 是否开启?
-
无论默认的 IMPLICIT_TRANSACTIONS 是什么,我都没碰过。
-
返回什么 SELECT @@OPTIONS & 2
-
0,所以它似乎关闭了。
-
请注意嵌套事务是一个谎言。 SQL Server 将计算
BEGIN TRANSACTION和COMMIT,当然,但只有一个事务在进行。保存点并没有真正改变这一点。它们只是让您能够部分回滚。将它与arcane rules that exist for when a transaction is doomed or not(也取决于XACT_ABORT)结合起来,你的手上真的是一团糟。
标签: sql-server transactions nested-transactions