Проверьте ограничение, обходя блок CATCH в распределенной транзакции

StackOverflow https://stackoverflow.com/questions/546781

Вопрос

У меня есть хранимая процедура MSSSQL, выполняющая распределенную транзакцию, которая выглядит следующим образом:

SET XACT_ABORT ON;
SET NOCOUNT ON;

BEGIN TRY
  BEGIN DISTRIBUTED TRANSACTION


  insert into LNKSRV.INST.dbo.zz (id, val) values (1, 'a');
  insert into LNKSRV.INST.dbo.zz (id, val) values (2, 'b');


  COMMIT TRANSACTION
END TRY
BEGIN CATCH
  if (XACT_STATE() <> 0) 
  BEGIN
    ROLLBACK TRANSACTION;
  END
  print ERROR_MESSAGE();
  print ERROR_LINE();
  print ERROR_SEVERITY();

END CATCH

Это работает нормально.

Если я добавлю этот третий оператор вставки:

  insert into LNKSRV.INST.dbo.zz (id, val) values ('error', 'b');

... это происходит неправильно - транзакция откатывается на удаленном сервере, управление передается блоку CATCH, и я получаю информацию об ошибке (не могу преобразовать «ошибку» в int).

Но если я добавлю этот оператор вставки:

  insert into LNKSRV.INST.dbo.zz (id, val) values (-1, 'b');

..и у меня есть ограничение проверки в удаленной таблице, требующее значений > 0 в столбце id, тогда все работает не так, как я ожидаю.Перевод ДЕЛАЕТ откатиться, но контролировать НЕ переход в блок улова.Вместо этого выполнение просто прекращается, и это выводится в окно вывода:

The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction

Почему?Мне нужно зарегистрировать эти ошибки в блоге catch.

Это было полезно?

Решение

Поскольку этим занимается координатор распределенных транзакций, при сбое транзакции в распределенной части транзакции DTC отправляет сообщение в форме предупреждения, которое останавливает выполнение вашего кода и которое TRY/CATCH не может обработать.

SQL Server может обнаружить на вашей стороне, когда вы пытаетесь вставить неправильный тип данных в таблицу (даже на удаленном экземпляре), но ограничение обрабатывается на связанном сервере, что приводит к отправке внимания в DTC и ваш TRY/ CATCH, который следует игнорировать.

Дополнительные сведения см. в первом разделе «Примечание» раздела «Использование TRY...CATCH в Transact-SQL» электронной документации по SQL Server 2008, расположенного по адресу:

http://msdn.microsoft.com/en-us/library/ms179296.aspx

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top