SQL Server-транзакции откатываются при ошибке?
у нас есть клиентское приложение, которое работает с некоторыми SQL на SQL Server 2005, например:
BEGIN TRAN;
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
COMMIT TRAN;
он отправляется одной длинной Строковой командой.
если одна из вставок завершается неудачно или какая-либо часть команды завершается неудачно, SQL Server откатывает транзакцию? Если он не откатывается, мне нужно отправить вторую команду, чтобы откатить его?
Я могу дать подробные сведения об api и языке, который я использую, но я думаю, что SQL Server должен отвечать одинаково для любой язык.
5 ответов:
можно поставить
set xact_abort on
перед вашей транзакцией, чтобы убедиться, что sql откатывается автоматически в случае ошибки.
Вы правы в том, что вся транзакция будет откачена. Вы должны выполнить команду, чтобы откатить его.
Вы можете обернуть это в
TRY CATCH
блок следующим образомBEGIN TRY BEGIN TRANSACTION INSERT INTO myTable (myColumns ...) VALUES (myValues ...); INSERT INTO myTable (myColumns ...) VALUES (myValues ...); INSERT INTO myTable (myColumns ...) VALUES (myValues ...); COMMIT TRAN -- Transaction Success! END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRAN --RollBack in case of Error -- you can Raise ERROR with RAISEERROR() Statement including the details of the exception RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1) END CATCH
из статьи MDSN, Управление Транзакциями (Компонент Database Engine).
Если ошибка оператора времени выполнения (например, нарушение ограничения) происходит в пакете, поведение по умолчанию в компоненте Database Engine заключается в откате только оператора, который вызвал ошибку. Это поведение можно изменить с помощью инструкции SET XACT_ABORT. После выполнения команды SET XACT_ABORT ON любая ошибка оператора времени выполнения вызывает автоматический откат текущей транзакции. Ошибки компиляции, такие как синтаксические ошибки, не зависят от SET XACT_ABORT. Дополнительные сведения см. В разделе SET XACT_ABORT (Transact-SQL).
в вашем случае он откатит полную транзакцию, когда какая-либо из вставок потерпит неудачу.
вот код с получением сообщения об ошибке работа с MSSQL Server 2016:
BEGIN TRY BEGIN TRANSACTION -- Do your stuff that might fail here COMMIT END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRAN DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE() DECLARE @ErrorSeverity INT = ERROR_SEVERITY() DECLARE @ErrorState INT = ERROR_STATE() -- Use RAISERROR inside the CATCH block to return error -- information about the original error that caused -- execution to jump to the CATCH block. RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ); END CATCH
если одна из вставок завершается неудачно или какая-либо часть команды завершается неудачно, SQL server откатывает транзакцию?
нет, это не так.
если он не откатывается, мне нужно отправить вторую команду, чтобы откатить его?
конечно, вы должны выдать
ROLLBACK
вместоCOMMIT
.если вы хотите решить, следует ли зафиксировать или откатить транзакцию, вы должны удалить
COMMIT
предложение из заявление, проверьте результаты вставок, а затем выдайте либоCOMMIT
илиROLLBACK
в зависимости от результатов проверки.