Всякий раз, когда в хранимой процедуре CLR, вызываемой из пакета служб SSIS, возникает исключение, в рамках транзакции 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
транзакция не создана и информация для основной ошибки
возвращается.