Sql server 2008 分布式发送失败时如何检索错误代码和消息?(MS DTC)

Sql server 2008 分布式发送失败时如何检索错误代码和消息?(MS DTC),sql-server-2008,try-catch,msdtc,distributed-transactions,xact-abort,Sql Server 2008,Try Catch,Msdtc,Distributed Transactions,Xact Abort,我们有一个存储过程,它通过一个具有不同MS SQL 2008数据库的链接服务器启动分布式事务 我们使用 SET XACT_ABORT ON; 而且 BEGIN TRY / CATCH blocks 围绕事务捕获任何错误,并将错误代码和消息返回给调用客户端 但是,当分布式事务中的命令失败时,似乎MS DTC正在接管控制,我们的catch块无法“正常”回滚并返回错误消息等。相反,出现了一个错误:Microsoft分布式事务协调器(MS DTC)已取消分布式事务。(错误1206) 有没有办

我们有一个存储过程,它通过一个具有不同MS SQL 2008数据库的链接服务器启动分布式事务

我们使用

  SET XACT_ABORT ON;
而且

  BEGIN TRY / CATCH blocks
围绕事务捕获任何错误,并将错误代码和消息返回给调用客户端

但是,当分布式事务中的命令失败时,似乎MS DTC正在接管控制,我们的catch块无法“正常”回滚并返回错误消息等。相反,出现了一个错误:Microsoft分布式事务协调器(MS DTC)已取消分布式事务。(错误1206)

有没有办法让catch块捕捉到这种分布式发送错误?

---更新--- 看起来这是一个已知问题,Microsoft不会解决它:

有一种解决方法,但使用SSI调用SP:


您应该能够使用XACT_STATE()回滚事务,并使用RAISERROR和@ERROR来提供更多详细信息

…代码在这里

结束尝试
开始捕捉

  DECLARE @errormsg VARCHAR(MAX)
  SET @errormsg = @@ERROR

  -- Test XACT_STATE:
      -- If 1, the transaction is committable.
      -- If -1, the transaction is uncommittable and should 
      --     be rolled back.
      -- XACT_STATE = 0 means that there is no transaction and
      --     a commit or rollback operation would generate an error.

  -- Test whether the transaction is uncommittable.
  IF (XACT_STATE()) = -1
  BEGIN
      ROLLBACK TRANSACTION;
  END;

  -- Test whether the transaction is committable.
  IF (XACT_STATE()) = 1
  BEGIN
      COMMIT TRANSACTION;   
  END;

  RAISERROR(@errormsg, 16, 1)
端接


第二个Rollback命令应该是commit,不是吗?可能只是个排版?但是catch块仍然没有真正执行,MS DTC仍在接管。例如,在rollback/commit命令之前插入print语句时,不会打印任何内容。此外,我没有看到通过RAISEERROR命令引发的错误消息,而是在我的OP中复制的通用MS DTC错误消息。我想我找到了答案,请参阅以下帖子:
  COMMIT TRANSACTION; 
  DECLARE @errormsg VARCHAR(MAX)
  SET @errormsg = @@ERROR

  -- Test XACT_STATE:
      -- If 1, the transaction is committable.
      -- If -1, the transaction is uncommittable and should 
      --     be rolled back.
      -- XACT_STATE = 0 means that there is no transaction and
      --     a commit or rollback operation would generate an error.

  -- Test whether the transaction is uncommittable.
  IF (XACT_STATE()) = -1
  BEGIN
      ROLLBACK TRANSACTION;
  END;

  -- Test whether the transaction is committable.
  IF (XACT_STATE()) = 1
  BEGIN
      COMMIT TRANSACTION;   
  END;

  RAISERROR(@errormsg, 16, 1)