Обработка транзакций в SQL Server 2005 игнорируется - PullRequest
2 голосов
/ 20 декабря 2011

Я вижу странное поведение, которое встречалось более одного раза для совершенно не связанных запросов.

Кажется, что оператор COMMIT TRANSACTION в запросе Sql игнорируется, несмотря на отсутствие ошибок, оставляя блокировку таблицы до тех пор, пока процесс не будет остановлен.

Вот один пример:

BEGIN TRY

BEGIN TRANSACTION 

    UPDATE Elements.ProductDeparture
    SET DurationDays = 5,       
        FinishDate = DATEADD(day, 4, DepartureDate)
    WHERE DepartureCode LIKE 'PPAF%'
    AND   ProductID = 2359

COMMIT TRANSACTION 
END TRY

BEGIN CATCH
    PRINT 'Error: ' + ERROR_MESSAGE()
    ROLLBACK
END CATCH

Нет ошибки, выходящей из запроса (если вы выполняете его без транзакции, она завершается нормально). Поведение воспроизводимо (т. Е. Оно происходит каждый раз, когда выполняется вышеуказанный запрос, а не только периодически).

Это уже дважды происходило для совершенно не связанных запросов, выполняемых в транзакциях.

Вот странный бит. Мы запустили его в нашей среде разработки и тестовой среде без проблем. Запуск его в Production приводит к тому, что процесс не завершается, удерживая блокировку на столе, пока процесс не будет завершен. Все они являются средами SQL Server 2005.

Существуют ли какие-либо настройки базы данных SQL Server, которые могут вызывать это странное поведение? До сих пор примерно 5 разработчиков смотрели на это и никогда не видели ничего подобного.

Ответы [ 2 ]

3 голосов
/ 20 декабря 2011

Некоторые мысли:

  • Использование SET XACT_ABORT ON для принудительного отката и разблокировки блокировки в случае любой ошибки
    Это также подавляет ошибку 266
  • Сначала проверьте существующую транзакцию
    Я подозреваю, что это ваша проблема
  • Проверка состояния транзакции перед откатом
  • ROLLBACK сама по себе ничего не делает: вам нужноTRAN или TRANSACTION.

Для получения дополнительной информации см .: Вложенные хранимые процедуры, содержащие шаблон TRY CATCH ROLLBACK?

Итак, вот так

SET XACT_ABORT, NOCOUNT ON

DECLARE @starttrancount int

BEGIN TRY
    SET @starttrancount = @@TRANCOUNT

    IF @starttrancount = 0
        BEGIN TRANSACTION

    UPDATE Elements.ProductDeparture
        SET DurationDays = 5,       
            FinishDate = DATEADD(day, 4, DepartureDate)
        WHERE DepartureCode LIKE 'PPAF%'
        AND   ProductID = 2359

    IF @starttrancount = 0 
        COMMIT TRANSACTION
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 AND @starttrancount = 0 
        ROLLBACK TRANSACTION
    PRINT 'Error: ' + ERROR_MESSAGE()
END CATCH
1 голос
/ 20 декабря 2011

Проверка переменной @@ TRANCOUNT - перед транзакцией - если она> 0 - тогда выполняется внешняя транзакция. Так что - в этом случае ваш коммит просто уменьшает значение @@ TRANCOUNT и фактически не фиксирует изменения

Только самые внешние коммиты (которые уменьшают @@ trancount до 0) исправляют изменения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...