Richtige Verwendung von Transaktionen in SQL Server

236

Ich habe 2 Befehle und muss beide korrekt ausführen oder keiner von ihnen ausgeführt. Ich glaube, ich brauche eine Transaktion, weiß aber nicht, wie ich sie richtig verwenden soll.

Was ist das Problem mit dem folgenden Skript?

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

Der INSERTBefehl wird ausgeführt, aber der UPDATEBefehl hat ein Problem.

Wie kann ich dies implementieren, um beide Befehle zurückzusetzen, wenn einer von ihnen einen Ausführungsfehler aufweist?

Saeid
quelle

Antworten:

513

Fügen Sie einen Try / Catch-Block hinzu. Wenn die Transaktion erfolgreich ist, werden die Änderungen festgeschrieben. Wenn die Transaktion fehlschlägt, wird die Transaktion zurückgesetzt:

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  
Darren
quelle
1
Sollte nicht BEGIN TRANSACTION [Tran1]hineingelegt werden TRY? Wie auch immer - sehr einfacher und eleganter Code.
Piotr Nawrot
4
@PiotrNawrot Nein, wenn die Transaktionserstellung fehlgeschlagen ist, muss sie nicht im Catch zurückgesetzt werden.
Monsignore
114

Zu Beginn der gespeicherten Prozedur sollte SET XACT_ABORT auf ON gesetzt werden , um SQL Server anzuweisen, die Transaktion im Fehlerfall automatisch zurückzusetzen. Wenn nicht angegeben oder auf AUS gesetzt, muss nach jeder Anweisung @@ ERROR getestet oder der Rollback- Block TRY ... CATCH verwendet werden .

Nikola Markovinović
quelle
2
Mit anderen Worten, Ihre Transaktion ist nicht atomar, es sei denn, Sie setzen zuerst XACT_ABORT ON.
4
Es ist schwer zu erkennen, wenn die URL unterstrichen wird, aber es gibt einen Unterstrich inXACT_ABORT
BurnsBA
32

Einfacher Ansatz:

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;
Bohdan
quelle