2011-11-10 33 views
2

每当异常在CLR从SSIS包调用的存储过程,抛出一个DTC事务中,客户端返回的错误(SSIS包),涉及到DTC而不是基本的例外。如何从CLR叫DTC交易从SSIS包存储过程中得到详细的错误

是否有可能有信息返回给客户端的底层错误?

注意:当存储过程从SQL Server Management Studio中运行分布式事务之外,则返回底层错误的详细信息。

Error: Executing the query "StoredProcedure” failed with the following error: “The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction”. Possible reasons: Problems with the query, “ResultSet” property not set correctly, parameters not set correctly, or connection not established correctly.

在单个SQL Server 2008实例上运行的所有代码。其再现问题

下面的代码说明了这个问题,但在标题中该客户所描述的情形不同

SSIS Package 
---> Sequence Container (TransactionOption = Required) 
---> Execute SQL Task (ADO.NET Connection Manager, SQLClient DataProvider) 
---> SQL Server CLR Stored Procedure (No exception handling code) 
---> TransactionScope(TransactionScopeOption.Required) 

代码是C#控制台应用程序,而不是一个SSIS包

CLR存储过程

using System; 
using System.Transactions; 

public partial class StoredProcedures 
{ 
    [Microsoft.SqlServer.Server.SqlProcedure] 
    public static void ExceptionStoredProcedure() 
    { 
     using (TransactionScope scope = new TransactionScope()) 
     { 
      throw new Exception(@"Test exception thrown from ""ExceptionStoredProcedure"""); 
     } 
    } 
}; 

C#控制台应用程序客户机

using System; 
using System.Data.SqlClient; 
using System.Transactions; 

namespace SQLCLRTester 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       using (TransactionScope scope = new TransactionScope()) 
       { 
        string connectionString = "Data Source=.; Initial Catalog=Experiments; Integrated Security=Yes"; 

        using (SqlConnection noOpConnection = new  SqlConnection(connectionString)) 
        { 
         noOpConnection.Open(); 

         using (SqlConnection connection = new SqlConnection(connectionString)) 
         { 
          SqlCommand command = 
           new SqlCommand() 
           { 
            CommandText = "ExceptionStoredProcedure", 
            CommandType = System.Data.CommandType.StoredProcedure, 
            Connection = connection 
           }; 
          connection.Open(); 
          command.ExecuteNonQuery(); 
         } 

        } scope.Complete(); 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Exception caught: {0}", ex.Message); 
      } 
     } 

    } 
} 

消息印刷通过客户端

捕获到异常:Microsoft分布式事务协调器(MS DTC)已取消分布式事务

注:

  1. 的InnerException是空
  2. 如果C# 控制台应用程序或CLR存储过程中的事务范围被删除,则不会创建DTC 事务并返回基础错误 的信息。
+0

找到工作,感谢身边的文章链接提供的 鲍勃Beauchemin(合作伙伴,MVP) – AtTheMoment

回答

0

找到一种解决方法,使用SqlContext.Pipe.Send()感谢 提供的链接Bob Beauchemin(合伙人,MVP)。见下面的代码。

注:SqlClient中追加 “信息消息” 由SQL Server发送到SqlException.Message因此使用的SqlClient不需要客户端代码改变

CLR存储过程

using System; 
using System.Transactions; 
using Microsoft.SqlServer.Server; 
using System.Data.SqlClient; 

public partial class StoredProcedures 
{ 
    [Microsoft.SqlServer.Server.SqlProcedure] 
    public static void ExceptionStoredProcedure() 
    { 
     using (TransactionScope scope = new TransactionScope()) 
     { 
      try 
      { 
       throw new Exception(@"Test exception thrown from  ""ExceptionStoredProcedure"""); 
       scope.Complete(); 
      } 
      catch (Exception ex) 
      { 
       if (Transaction.Current.TransactionInformation.DistributedIdentifier != Guid.Empty) 
        SqlContext.Pipe.Send(ex.Message); 

       throw; 
      } 
     } 
    } 


}; 

留言印刷按客户

捕获到异常:Microsoft分布式事务处理协调器(MS DTC)已经取消了DIS致敬交易。

从“ExceptionStoredProcedure”

可能的解释

抛出检验异常基于由Bob发现了大约DTC事务文章链接中断和T-SQL的try/catch我认为,观察到的行为可以展开如下:

  1. CLR存储过程中事务范围中的异常导致 事务中止投票发送到DTC。
  2. DTC发送中止请求所有应征入伍的资源管理器 包括SQL Server
  3. SQL服务器转换中止请求转换成一个注意信号的 SQL服务器会话中,CLR存储过程执行
  4. 注意信号的变化如何SQL Server的CLR代码托管对待与在异常消息 进而导致不被纳入结果 未处理的异常CLR返回到客户端

链接艺术icles:

http://connect.microsoft.com/SQLServer/feedback/details/414969/uncatchable-error-when-distributed-transaction-is-aborted

http://msdn.microsoft.com/en-us/library/ms179296(SQL.90).aspx