我在 SQL Server 2008R2 上有流程场景:
• 一个usp 收集数据,然后在两个SQL Server 之间传输数据
此过程将在流程的所有级别(usp、SSIS 和触发器)的事务中完成
在将数据传输到 DB7.dbo.Dest 的数据流中,该表有一个 AFTER INSERT 触发器,它将刚刚通过的数据插入到最终表 DB7.dbo.FinalDestination 中:
CREATE TRIGGER [dbo].[Insert_OnStaging] ON [dbo].[Dest]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON; --Rollsback complete transaction if there are any errors
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO [DB7].[dbo].[FinalDestination] WITH (TABLOCK)
(Column1
,Column2
)
SELECT I.Column1, I.Column2
FROM INSERTED I
INNER JOIN [DB7].[dbo].[Dest] PR
ON I.IDcol = PR.IDcol
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 AND XACT_STATE() <> 0
ROLLBACK TRANSACTION;
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
DECLARE @ErrorLine INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE(),
@ErrorLine = ERROR_LINE()
;
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState, -- State.
@ErrorLine --Error Line
);
END CATCH;
END
在每个级别,由于数据的敏感性正确并完全进入决赛桌,我都试图对数据进行防御。
关于 SSIS,从我阅读和测试的内容来看,它似乎工作正常。
我最担心的是我在上面编写的触发器。根据我的阅读和理解,设置 XACT_ABORT ON 将在出现任何错误时回滚 TRY 块内的事务(换句话说,存在不可提交的事务)。在这种情况下,我继续在 CATCH 块中添加回滚事务部分作为一个想法,因为它永远不会到达(根据我的理解)。同时,我添加了 WITH (TABLOCK) 选项,以便在执行 INSERT 时锁定表。
在触发器的情况下,在 XACT_ABORT 为 ON 的情况下,TRY...CATCH 是否必要?TRY 块内是否需要 COMMIT TRANSACTION?正如我也看到它在基于 @@TRANCOUNT 的 CATCH 块之后提交
BEGIN TRY
BEGIN TRANSACTION
[Tsql here]
END TRY
BEGIN CATCH
[Error Handling]
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRANSACTION
END
欢迎回答和批评,并在此先感谢您。当我试图概括名称时,请原谅任何错别字......