检查约束绕过CATCH块分布式事务
-
23-08-2019 - |
题
我具有执行分布式事务,看起来像这样一个MSSSQL存储过程:
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
此工作正常。
如果我添加此第三插入语句:
insert into LNKSRV.INST.dbo.zz (id, val) values ('error', 'b');
...它正确失败 - 事务被回滚在远程服务器上,并且控制通向CATCH块和我得到有关错误的信息(不能转换“错误”为int)
但是,如果我添加此插入语句:
insert into LNKSRV.INST.dbo.zz (id, val) values (-1, 'b');
..和我有需要在ID列中的值> 0远程表检查contraint,然后事情不作为我期望工作。事务 DOES 回滚,但控制的不转移到catch块。取而代之的是,执行只是模具和该被打印到输出窗口:
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction
为什么呢?我需要在catch博客来记录这些错误。
解决方案
由于分布式事务协调器处理此,当交易上交易的分布式部件发生故障时,DTC发送中的注意的形式,其从执行停止代码中的消息,并且其中所述TRY / CATCH不能过程
SQL Server可以在您的最终检测,当你试图插入一个不正确的数据类型为表(即使在远程实例),但约束链接的服务器,这会导致注意力集中在处理被发送到DTC和你的try / catch被忽略。
有关详细信息,请参阅SQL Server 2008联机丛书,位于一节中的“在Transact-SQL中使用TRY ... CATCH”的第一个“注”部分:
不隶属于 StackOverflow