Транзакционные обновления, которые применяются к БД независимо от фиксации или отката - PullRequest
0 голосов
/ 05 февраля 2010

У меня сложилось впечатление, что все обновления базы данных сервера SQL сначала добавляются в T-Log, а затем применяются к базовой базе данных. В случае сбоя сервера процесс восстановления будет выполнять откат любых незавершенных транзакций. Я также предположил, что это работает с транзакциями, если фиксация или откат не вызваны, изменения не будут внесены.

Итак, я хотел увидеть реакцию SQL-сервера на прерывание транзакций. то есть обновления транзакций без фиксации или отката. То, что я обнаружил, я не совсем понимаю. Особенно, как SQL-сервер может позволить этому случиться.

Я использовал приведенный ниже скрипт для вставки строк в таблицу с задержкой, чтобы дать мне достаточно времени, чтобы остановить транзакцию до того, как она достигнет фиксации или отката. Это, я думаю, имитирует тайм-аут клиентского приложения до завершения транзакции.

    Create Table MyTest (Comment varchar(20))
Go
Create Procedure MyProc 

as

Begin Try
    Begin Transaction

        Insert Into MyTest Select 'My First Entry'

        WaitFor Delay '00:00:02'

        Insert Into MyTest Select 'My Second Entry'

        WaitFor Delay '00:00:02'

        Insert Into MyTest Select 'My Third Entry'

    Commit Transaction

    Return 0 -- success
End Try

Begin Catch
    If (@@trancount<>0) Rollback Transaction

    Declare @err int, @err_msg varchar(max)
    Select @err = error_number(), @err_msg = error_message()
    Raiserror(@err_msg, 16,1)

    Return @err
End Catch

Если вы запустите скрипт, в зависимости от того, как быстро вы остановите процедуру, вы увидите, что первые одна или две вставки останутся в таблице. Может ли кто-нибудь объяснить, почему это произошло?

Select * From MyTest

Я проверял это на SQL 2008.

Ответы [ 2 ]

2 голосов
/ 05 февраля 2010

Правильно, TXN записываются с использованием «Write Ahead Logging». Есть статьи MSDB об этом и как это взаимодействует с коммитом / откатом / контрольными точками и т. Д.

Однако время ожидания команды (или то, что вы делаете, просто останавливает выполнение кода), и TXN никогда не откатывается и блокируется, пока соединение не будет закрыто (или не будет выполнено позже отдельно). Это то, что SET XACT_ABORT для

1 голос
/ 05 февраля 2010

Если вы начнете транзакцию и не будете ее фиксировать или откатывать, вы просто получите зависшую транзакцию, которая может блокировать других пользователей, пока что-то не будет сделано с текущей транзакцией. SQL Server не будет автоматически фиксировать или откатывать транзакцию самостоятельно, просто потому, что ваш код этого не сделал. Транзакция будет оставаться на месте и блокировать других пользователей, пока она не будет зафиксирована или откатана.

Теперь я могу довольно легко начать транзакцию в своем коде T-SQL, не фиксировать или откатывать ее, выполнить инструкцию Select и посмотреть, какие данные я только что вставил или обновил, пока инструкция Select использует такое же соединение, как и моя транзакция. Если я попытаюсь сделать выбор с использованием другой транзакции, я не увижу вставленные или обновленные данные. Фактически, оператор Select может не завершиться вообще, пока транзакция по другому соединению не будет завершена.

...