如何从SSIS包中的DTC事务中调用的CLR存储过程中获取详细错误

时间:2011-11-10 18:29:30

标签: ssis sqlclr msdtc

每当在SSR包中调用的CLR存储过程中抛出异常时,在DTC事务中,返回给客户端的错误(SSIS包)与DTC而不是基础异常有关。

是否可以将基础错误的信息返回给客户?

注意:当从SQL Server Management Studio运行存储过程时,在分布式事务之外,将返回基础错误的详细信息。

  

错误:执行查询“StoredProcedure”失败,并显示以下内容   错误:“Microsoft分布式事务处理协调器(MS DTC)具有   取消了分发的交易“。可能的原因:问题   与查询,“ResultSet”属性设置不正确,参数不正确   设置正确,或连接未正确建立。

所有代码都在单个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为null
  2. 如果C#中的事务范围 控制台应用程序或CLR存储过程被删除然后DTC 未创建事务和基础错误的信息 归还。

1 个答案:

答案 0 :(得分: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)已取消分布式事务。

测试从“ExceptionStoredProcedure”抛出的异常

可能的解释

根据Bob发现的关于DTC事务中止和T-SQL TRY / CATCH的文章链接,我认为观察到的行为可能如下所示:

  1. CLR存储过程中事务范围的异常导致a 交易中止投票将被发送到DTC。
  2. DTC向所有登记的资源管理器发送中止请求 包括SQL Server
  3. SQL Server将中止请求转换为注意信号 正在执行CLR存储过程的SQL Server会话
  4. 注意信号会更改SQL Server CLR托管代码处理的方式 未处理的CLR异常反过来导致异常消息 未包含在返回客户的结果中
  5. 文章链接:

    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