Любые идеи для ROLLBACK TRANSACTION в этом операторе SQL - PullRequest
3 голосов
/ 16 ноября 2011

Может кто-нибудь помочь мне с этим оператором SQL.Я запускаю его на ядре SQL Server.

У меня есть следующий оператор, который удаляет все записи в таблице и заменяет их новыми:

SET XACT_ABORT ON;
BEGIN TRANSACTION;
DELETE FROM [t1] WHERE [id]>10;
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a1', 'b1' FROM [t1];
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a2', 'b2' FROM [t1];
--and so on, I may have up to 100 of these inserts
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'aN', 'bN' FROM [t1];
COMMIT;
SET XACT_ABORT OFF;

Я хочу знать, какВы используете ROLLBACK в случае неудачной транзакции?

PS.В основном мне нужно вернуть базу данных к тому, что было раньше в случае любой ошибки в этом утверждении выше.

РЕДАКТИРОВАТЬ: Обновлено с SET XACT_ABORT ON;Заявление предлагается ниже.Это как должно выглядеть?

Ответы [ 5 ]

4 голосов
/ 16 ноября 2011

@ Одед рассмотрел хороший подход для автоматической обработки вашего отката.Для полноты, я дам вам другой метод для явного решения этой ситуации с помощью try catch .

BEGIN TRANSACTION;

BEGIN TRY
    DELETE FROM [t1] WHERE [id]>10;
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a1', 'b1' FROM [t1];
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a2', 'b2' FROM [t1];
    --and so on, I may have up to 100 of these inserts
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'aN', 'bN' FROM [t1];
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO
4 голосов
/ 16 ноября 2011

Вам нужно установить SET XACT_ABORT ON, если вы хотите, чтобы транзакция полностью откатилась при ошибке.

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

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

См. Документацию для XACT_ABORT.

1 голос
/ 16 ноября 2011

Вы не упомянули свою версию SQL Server - но, начиная с версии 2005, вы можете использовать обработку исключений в стиле BEGIN TRY... END TRY BEGIN CATCH... END CATCH.

Обычно я оборачиваю свои блоки операторов в скелет блока транзакции / try-catch примерно так:

BEGIN TRANSACTION
BEGIN TRY

    -- put your statements to be executed *HERE*    

    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

    ROLLBACK TRANSACTION
END CATCH

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

1 голос
/ 16 ноября 2011

http://www.codeproject.com/KB/database/sqlservertransactions.aspx

Вышесказанное может дать вам представление.

0 голосов
/ 16 ноября 2011

Вы можете попробовать следующий метод:

BEGIN TRY
   BEGIN TRANSACTION 
     DELETE FROM tablename WHERE id>1
     --- set of your querys 
    COMMIT
END TRY

BEGIN CATCH 
    IF @@TRANCOUNT > 0  
       ROLLBACK 
END CATCH
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...