【发布时间】: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) 已取消分布式事务
注意事项:
- InnerException 为空
- 如果事务范围在 C# 控制台应用程序或 CLR 存储过程中被删除然后一个 DTC 交易未创建,基础错误的信息 被退回。
【问题讨论】:
-
通过 Bob Beauchemin(合伙人,MVP)提供的文章链接找到了解决方法