0

我有一個MSSSQL存儲過程執行的分佈式事務處理看起來是這樣的:檢查Contraint繞過CATCH塊在分佈式事務處理

SET XACT_ABORT ON; 
SET NOCOUNT ON; 

BEGIN TRY 
    BEGIN DISTRIBUTED TRANSACTION 


    insert into LNKSRV.INST.dbo.zz (id, val) values (1, 'a'); 
    insert into LNKSRV.INST.dbo.zz (id, val) values (2, 'b'); 


    COMMIT TRANSACTION 
END TRY 
BEGIN CATCH 
    if (XACT_STATE() <> 0) 
    BEGIN 
    ROLLBACK TRANSACTION; 
    END 
    print ERROR_MESSAGE(); 
    print ERROR_LINE(); 
    print ERROR_SEVERITY(); 

END CATCH 

這工作得很好。

如果我添加這3插入語句:

insert into LNKSRV.INST.dbo.zz (id, val) values ('error', 'b'); 

...它正確地失敗 - 事務回滾遠程服務器上,並控制傳遞到catch塊,我得到有關該錯誤信息(不能將'錯誤'轉換爲int)。

但如果我添加此插入語句:

insert into LNKSRV.INST.dbo.zz (id, val) values (-1, 'b'); 

..和我有需要> 0的ID列值的遠程表的檢查contraint,那麼事情不會如我所料工作。交易DOERS回滾,但控制不是轉移到catch塊。相反,執行就會死亡,並將其打印到輸出窗口:

The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction 

爲什麼?我需要在catch博客中記錄這些錯誤。

回答

2

由於分佈式事務協調器正在處理此事務,所以當事務的分佈式部分事務失敗時,DTC會以注意的形式發送消息,從而阻止您的代碼執行以及TRY/CATCH無法處理。

當您嘗試向表中插入不正確的數據類型(即使在遠程實例上)時,SQL Server可以檢測到您的端點,但在鏈接的服務器上處理約束時會導致將注意力發送到DTC你的TRY/CATCH被忽略。

欲瞭解更多信息,請參見SQL Server 2008聯機叢書的部分 「在Transact-SQL中使用TRY ... CATCH」 的第一個 「注」 部分,位於:

http://msdn.microsoft.com/en-us/library/ms179296.aspx

+0

所以你的答案是,「我搞砸了」? : - | – Clyde 2009-02-13 18:57:05