Utilisation correcte des transactions dans SQL Server


236

J'ai 2 commandes et j'ai besoin que les deux soient exécutées correctement ou qu'aucune ne soit exécutée. Je pense donc que j'ai besoin d'une transaction, mais je ne sais pas comment l'utiliser correctement.

Quel est le problème avec le script suivant?

BEGIN TRANSACTION [Tran1]

INSERT INTO [Test].[dbo].[T1]
    ([Title], [AVG])
VALUES ('Tidd130', 130), ('Tidd230', 230)

UPDATE [Test].[dbo].[T1]
  SET [Title] = N'az2' ,[AVG] = 1
  WHERE [dbo].[T1].[Title] = N'az'

COMMIT TRANSACTION [Tran1]
GO

La INSERTcommande est exécutée, mais la UPDATEcommande a un problème.

Comment puis-je implémenter cela pour restaurer les deux commandes si l'une d'entre elles a une erreur d'exécution?

Réponses:


513

Ajoutez un bloc try / catch, si la transaction réussit, elle valide les modifications, si la transaction échoue, la transaction est annulée:

BEGIN TRANSACTION [Tran1]

  BEGIN TRY

      INSERT INTO [Test].[dbo].[T1] ([Title], [AVG])
      VALUES ('Tidd130', 130), ('Tidd230', 230)

      UPDATE [Test].[dbo].[T1]
      SET [Title] = N'az2' ,[AVG] = 1
      WHERE [dbo].[T1].[Title] = N'az'

      COMMIT TRANSACTION [Tran1]

  END TRY

  BEGIN CATCH

      ROLLBACK TRANSACTION [Tran1]

  END CATCH  

1
Ne devrait pas BEGIN TRANSACTION [Tran1]être placé à l'intérieur TRY? Quoi qu'il en soit - morceau de code très simple et élégant.
Piotr Nawrot

4
@PiotrNawrot Non, si la création de la transaction a échoué, il n'est pas nécessaire de l'annuler dans la capture.
Monseigneur

114

Au début de la procédure stockée, il faut mettre SET XACT_ABORT ON pour demander au serveur SQL de restaurer automatiquement la transaction en cas d'erreur. Si omis ou réglé sur OFF, il faut tester @@ ERROR après chaque instruction ou utiliser le bloc de restauration TRY ... CATCH .


2
En d'autres termes, votre transaction n'est pas atomique sauf si vous définissez d'abord XACT_ABORT ON.
4h du

Il est difficile de voir avec un soulignement d'URL, mais il y a un trait de soulignement dansXACT_ABORT
BurnsBA

32

Approche facile:

CREATE TABLE T
(
    C [nvarchar](100) NOT NULL UNIQUE,
);

SET XACT_ABORT ON -- Turns on rollback if T-SQL statement raises a run-time error.
SELECT * FROM T; -- Check before.
BEGIN TRAN
    INSERT INTO T VALUES ('A');
    INSERT INTO T VALUES ('B');
    INSERT INTO T VALUES ('B');
    INSERT INTO T VALUES ('C');
COMMIT TRAN
SELECT * FROM T; -- Check after.
DELETE T;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.