260 votes

Utilisation correcte des transactions dans SQL Server

J'ai deux commandes et j'ai besoin que les deux soient exécutées correctement ou qu'aucune ne soit exécutée. Je pense donc avoir 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

Le site INSERT est exécutée, mais la commande UPDATE a un problème.

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

564voto

Darren Davies Points 29038

Ajoutez un bloc try/catch, si la transaction réussit, elle validera les changements, si la transaction échoue, elle sera 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 votes

Il ne faut pas BEGIN TRANSACTION [Tran1] être placé à l'intérieur TRY ? Quoi qu'il en soit, ce code est très simple et élégant.

13 votes

@PiotrNawrot Non, si la création de la transaction a échoué, il n'est pas nécessaire de la rétablir dans le catch.

3 votes

Si vous voulez voir l'erreur, alors incluez ceci dans le catch : SELECT ERROR_MESSAGE() AS ErrorMessage;

121voto

Nikola Markovinović Points 12039

Au début de la procédure stockée, il faut mettre METTRE XACT_ABORT ON pour demander à Sql Server d'annuler automatiquement la transaction en cas d'erreur. Si elle est omise ou réglée sur OFF, il faut tester les éléments suivants @@ERROR après chaque déclaration ou utilisation ESSAYER ... CATCH rollback bloc.

2 votes

En d'autres termes, votre transaction n'est pas atomique si vous ne réglez pas d'abord XACT_ABORT ON.

3 votes

C'est difficile à voir avec le soulignement d'url, mais il y a un soulignement dans XACT_ABORT

37voto

Bohdan Points 1882

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;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X