Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 检查分布式事务中绕过CATCH块的containt_Sql Server_Tsql_Error Handling_Transactions_Distributed Transactions - Fatal编程技术网

Sql server 检查分布式事务中绕过CATCH块的containt

Sql server 检查分布式事务中绕过CATCH块的containt,sql-server,tsql,error-handling,transactions,distributed-transactions,Sql Server,Tsql,Error Handling,Transactions,Distributed Transactions,我有一个执行分布式事务的MSSQL存储过程,如下所示: 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

我有一个执行分布式事务的MSSQL存储过程,如下所示:

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
…它正确地失败了--事务在远程服务器上回滚,控制传递到CATCH块,我得到有关错误的信息(无法将“error”转换为int)

但如果我添加此insert语句:

  insert into LNKSRV.INST.dbo.zz (id, val) values ('error', 'b');
  insert into LNKSRV.INST.dbo.zz (id, val) values (-1, 'b');
..我在远程表上有一个检查约束,要求id列中的值大于0,然后事情就不像我期望的那样工作了。事务会回滚,但控制不会转移到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”部分的第一个“注意”部分,位于:


所以你的答案是,“我完蛋了”?:-|@克莱德:不完全是,你会在调用数据库代码的任何级别上处理它。例外情况会在那里出现,并可能在那里被捕获。