SQL While循环重试事务直到成功

时间:2015-08-28 19:47:11

标签: sql sql-server while-loop transactions

我需要一个事务,当它失败时,回滚并重试。

到目前为止我在哪里:

CREATE PROCEDURE [dbo].[Save]
@MasterID as bigint

AS

BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
Declare @successtrans bit = 0

While @successtrans = 0
    Begin -- while
        BEGIN TRY
            BEGIN TRANSACTION

                DELETE SomeRecords WHERE ParentRecordID = @MasterID

                INSERT INTO SomeRecords 
                Select FieldOne, FieldTwo, FieldThree, ParentRecordID
                FROM OtherRecords 
                WHERE ParentRecordID = @MasterID

                INSERT INTO AnotherTable
                SELECT FieldA, FieldB, FieldC, FieldD
                FROM MoreRecords
                WHERE FieldD = @MasterID

            COMMIT TRANSACTION
            set @successtrans = 1
        END TRY
        BEGIN CATCH

                IF(XACT_STATE()) = -1 -- Determine the state of the current transction (1 = committable, 0 = no active transaction (same as @@Trancount check), -1 = active, but uncommittable) only on severity 17 or higher
                BEGIN
                    DECLARE @ErrorNumber bigint = ERROR_Number(),
                        @ErrorSeverity int = ERROR_SEVERITY(),
                        @ErrorState int = ERROR_STATE(),
                        @ErrorProcedure varchar(100) = ERROR_PROCEDURE(),
                        @ErrorLine int = ERROR_LINE(),
                        @ErrorMessage varchar(Max) = ERROR_MESSAGE()
                    IF @@TRANCOUNT > 0
                        ROLLBACK TRANSACTION
                    INSERT INTO ErrorLog(ErrorNumber, ErrorSeverity, ErrorState, ErrorProcedure, ErrorLine, ErrorMessage, ErrorDate)
                    VALUES(@ErrorNumber, @ErrorSeverity, @ErrorState, @ErrorProcedure, @ErrorLine, @ErrorMessage, GETDATE())
                END -- if
        END CATCH
    End -- while
END -- proc
GO

问题是,这对我正在做的事情有用吗?逻辑说是的。但这是我需要在10个或更多存储过程中实现的方法,而我却无法使其失败并重复。

1 个答案:

答案 0 :(得分:0)

你应该检查它为什么会失败,或者你可以生成一个无限循环(就像已经存在的主键一样)。

由于我不知道你为什么要这样做,我不会说这是一个糟糕的设计,但它确实很可疑。如果它失败是出于某种原因,异常消息会告诉你原因,而不是"暴力强迫"你的数据库,直到它做你期望你应该攻击问题的原因(坏数据?并发?很多原因可能导致异常)

编辑:你也应该照顾你的日志,在一个无限循环上它最终将填满你的硬盘