2011-12-20 4 views
2

Я вижу странное поведение, которое произошло более одного раза для совершенно несвязанных запросов.Ошибка транзакции SQL Server 2005

Оператор 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 

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

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

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

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

+0

Deadlock? И если я правильно помню, 1 процесс не эквивалентен одному оператору SQL - процесс может использоваться несколькими соединениями. –

ответ

1

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

Только самый внешний совершающие (который декрементах @@ TRANCOUNT до 0) делать фиксирует правки

3

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

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

Для получения дополнительной информации см это: Nested stored procedures containing TRY CATCH ROLLBACK pattern?

Так что, как этот

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 
Смежные вопросы