Как получить код ошибки и сообщение при сбое распределенной передачи? (MS DTC)

У нас есть хранимая процедура, которая запускает распределенную транзакцию через связанный сервер с различными базами данных MS SQL 2008.

Мы используем

  SET XACT_ABORT ON;

а также

  BEGIN TRY / CATCH blocks

вокруг транзакции, чтобы поймать любые ошибки и вернуть код ошибки и сообщение обратно вызывающему клиенту.

Однако, когда команда внутри распределенной транзакции завершается неудачно, кажется, что MS DTC берет на себя управление, и наш блок catch не может откатиться "изящно" и вернуть сообщение об ошибке и т. Д. Вместо этого возникает ошибка: координатор распределенных транзакций Microsoft (MS DTC) отменил распределенную транзакцию. (Ошибка 1206).

Есть ли способ, что такая распределенная ошибка передачи передается блоком catch?

1 ответ

Решение

---ОБНОВИТЬ---

Похоже, это известная проблема, и Microsoft не собирается ее исправлять: http://connect.microsoft.com/SQLServer/feedback/details/414969/uncatchable-error-when-distributed-transaction-is-aborted

Есть обходной путь, но использует SSIS для вызова SP: http://social.msdn.microsoft.com/Forums/en/sqlnetfx/thread/02e43cad-ac11-45fa-9281-6b4959929be7


Вы должны иметь возможность использовать XACT_STATE() для отката транзакции и RAISERROR в сочетании с @@ERROR, чтобы дать вам более подробную информацию

  SET NOCOUNT ON
  SET XACT_ABORT ON
          BEGIN TRY
      BEGIN TRANSACTION

..код идет здесь

  COMMIT TRANSACTION; 

КОНЕЦ ПОПРОБУЙТЕ
НАЧАТЬ ЛОВУТЬ

  DECLARE @errormsg VARCHAR(MAX)
  SET @errormsg = @@ERROR

  -- Test XACT_STATE:
      -- If 1, the transaction is committable.
      -- If -1, the transaction is uncommittable and should 
      --     be rolled back.
      -- XACT_STATE = 0 means that there is no transaction and
      --     a commit or rollback operation would generate an error.

  -- Test whether the transaction is uncommittable.
  IF (XACT_STATE()) = -1
  BEGIN
      ROLLBACK TRANSACTION;
  END;

  -- Test whether the transaction is committable.
  IF (XACT_STATE()) = 1
  BEGIN
      COMMIT TRANSACTION;   
  END;

  RAISERROR(@errormsg, 16, 1)

КОНЕЦ ЛОВ

Другие вопросы по тегам