[英]SQL Server transaction with multiple updates, inserts
因此,我们有一个在早晨SQL作业中使用的多个存储过程,并且按顺序调用过程。 如果proc中的一个查询失败,我们会为每个查询捕获/记录错误,因此我们确切地知道哪个块失败了。 但问题是,如果出现故障,其中一些进程很难重新开始,所以我想在每个存储过程中实现TRANSACTION
。
目前的程序与此类似:
CREATE PROCEDURE [dbo].[spStep01]
(
@Return_Message Varchar(1024) OUT -- Error messages returned to the calling program
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ErrorCode int
DECLARE @ApplicationNumber int
DECLARE @TaskNumber int
DECLARE @TaskCompleted smallint
DECLARE @TaskFailed smallint
DECLARE @TaskRunning smallint
DECLARE @ErrorSeverity smallint
DECLARE @ErrorState smallint
SELECT @ErrorCode = @@ERROR
SELECT @ApplicationNumber = 10
SELECT @TaskNumber = 1
SELECT @TaskCompleted = 0
SELECT @TaskFailed = -1
SELECT @TaskRunning = 1
SELECT @ErrorSeverity = 16
SELECT @ErrorState = 1
/***************************************************************************
* first insert
***************************************************************************/
BEGIN TRY
INSERT INTO ...
END TRY
BEGIN CATCH
SELECT @Return_Message = 'FAILED - first insert did not populate'
EXEC dbo.spTrackTask '', @ApplicationNumber, @TaskNumber, @TaskFailed, @Return_Message
RAISERROR (@Return_Message, @ErrorSeverity, @ErrorState)
RETURN
END CATCH
/***************************************************************************
* second insert
***************************************************************************/
BEGIN TRY
INSERT INTO ...
END TRY
BEGIN CATCH
SELECT @Return_Message = 'FAILED - second insert did not populate'
EXEC dbo.spTrackTask '', @ApplicationNumber, @TaskNumber, @TaskFailed, @Return_Message
RAISERROR (@Return_Message, @ErrorSeverity, @ErrorState)
RETURN
END CATCH
/***************************************************************************
* Procedure has completed successfully
***************************************************************************/
SELECT @Return_Message = 'SUCCESS - Inserts were complete'
EXEC dbo.spTrackTask '', @ApplicationNumber, @TaskNumber, @TaskCompleted, @Return_Message
/*************************************
* Get the Error Message for @@Error
*************************************/
IF @ErrorCode <> 0
BEGIN
SELECT @Return_Message = [Description] -- Return the SQL Server error
FROM master.dbo.SYSMESSAGES
WHERE error = @ErrorCode
END
/*************************************
* Return from the Stored Procedure
*************************************/
RETURN @ErrorCode -- =0 if success, <>0 if failure
END
我想要确定的是,如果我将所有TRY/CATCH
块包装在TRANSACTION
,如果它将回滚所有内容,则会引发错误。 我查看了SO并找到了一个TRY/CATCH
块的例子 ,但是我们在大多数存储过程中会有多个。 我没有太多的交易经验,所以我不能100%确定如何在这种情况下正确实现它。
将它包装在TRANSACTION
吗? 或者有更好的方法吗?
这个怎么样
BEGIN TRANSACTION tx
BEGIN TRY
@CurrentStep = "First Insert"
INSERT ...
@CurrentStep = "Second Insert"
INSERT ...Second
IF @@TRANCOUNT > 0
BEGIN --SUCCESS, nothing failed, now I can commit!!
SELECT @Return_Message = 'SUCCESS - Inserts were complete'
EXEC dbo.spTrackTask '', @ApplicationNumber, @TaskNumber, @TaskCompleted, @Return_Message
COMMIT TRANSACTION tx; -- now everything is committed
END
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 --something failed
BEGIN
IF @CurrentStep = 'First Insert'
SELECT @Return_Message = 'FAILED - first insert did not populate'
ELSE IF @CurrentStep = 'Second Insert'
SELECT @Return_Message = 'FAILED - second insert did not populate'
EXEC dbo.spTrackTask '', @ApplicationNumber, @TaskNumber, @TaskFailed, @Return_Message
RAISERROR (@Return_Message, @ErrorSeverity, @ErrorState)
ROLLBACK TRAN tx; -- everything is rolled back
END
END CATCH
希望这能为您解决问题,请记住,事务中的所有内容都应该在一个地方提交或回滚,否则您最好有多个交易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.