每当在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)已取消分布式事务
注意:
答案 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的文章链接,我认为观察到的行为可能如下所示:
文章链接:
http://msdn.microsoft.com/en-us/library/ms179296(SQL.90).aspx