SQL Server不匹配的BEGIN和COMMIT语句数嵌套事务

时间:2017-10-11 09:28:42

标签: sql-server transactions nested-transactions

我在一个事务中遵循了推荐的错误处理模板,该事务在现有事务中执行时应该有效。

这是我的模板

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

如果我用RAISERROR替换TRY块中的THROW,问题仍然存在。

测试结果:

事务中的EXEC失败场景:更正结果(给出正确的错误消息)

交易中的EXEC成功案例:出现意外错误。

  

EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配。先前的计数= 1,当前计数= 2.

交易外的EXEC失败场景:给出了预期的错误。

交易外的EXEC成功案例:出现意外错误。错误与上面的错误相同,但每次执行时,它都会增加-1。这是否意味着每次更多的东西保持未提交?

这是测试的样子:

BEGIN TRANSACTION
  EXEC ...
ROLLBACK TRANSACTION

有谁知道出了什么问题?

1 个答案:

答案 0 :(得分:0)

取消注释var

CREATE PROCEDURE DoSomething
AS
BEGIN
SET NOCOUNT ON
DECLARE @trans INTEGER = @@TRANCOUNT

IF (@trans > 0)
    SAVE TRANSACTION SavePoint
ELSE
    BEGIN TRANSACTION

BEGIN TRY
    DECLARE @f float;
    SET @f = 0;
    --var 1.
    --print  1/0
    --var 2.
    print LOG(@f)     
    --var ok
    --print 'ok'
END TRY

BEGIN CATCH             
    IF (@trans > 0 AND XACT_STATE() <> -1)
    BEGIN
        PRINT 'ROLLBACK SavePoint'
        ROLLBACK TRANSACTION SavePoint
    END
    PRINT 'Error'
END CATCH
END

执行

BEGIN TRANSACTION   
EXEC DoSomething 

IF XACT_STATE() = -1      
BEGIN   
    PRINT 'ROLLBACK XACT'
    ROLLBACK 
END

IF @@TRANCOUNT > 0 
BEGIN
    PRINT 'COMMIT'
    COMMIT 
END