【问题标题】:How to get detailed error from CLR Stored Procedure called in DTC transaction from SSIS Package如何从 SSIS 包的 DTC 事务中调用的 CLR 存储过程中获取详细错误
【发布时间】:2011-11-10 18:29:29
【问题描述】:

每当从 SSIS 包调用的 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 为空
  2. 如果事务范围在 C# 控制台应用程序或 CLR 存储过程中被删除然后一个 DTC 交易未创建,基础错误的信息 被退回。

【问题讨论】:

  • 通过 Bob Beauchemin(合伙人,MVP)提供的文章链接找到了解决方法

标签: ssis sqlclr msdtc


【解决方案1】:

感谢提供的链接,找到了使用 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 存储过程中事务范围内的异常会导致 要发送给 DTC 的交易中止投票。
  2. DTC 向所有登记的资源管理器发送中止请求 包括 SQL Server
  3. SQL Server 将中止请求转换为注意信号给 执行 CLR 存储过程的 SQL Server 会话
  4. 注意信号改变了 SQL Server CLR 托管代码的处理方式 未处理的 CLR 异常,进而导致异常消息 未包含在返回给客户端的结果中

文章链接:

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

【讨论】:

    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 2020-10-23
    • 2015-09-21
    • 2022-08-02
    • 1970-01-01
    • 2013-12-05
    • 2010-09-12
    • 1970-01-01
    相关资源
    最近更新 更多