Penggunaan transaksi yang benar dalam SQL Server


236

Saya punya 2 perintah dan perlu keduanya dieksekusi dengan benar atau tidak ada yang dieksekusi. Jadi saya pikir saya perlu transaksi, tetapi saya tidak tahu bagaimana menggunakannya dengan benar.

Apa masalah dengan skrip berikut?

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

The INSERTperintah dijalankan, tetapi UPDATEperintah memiliki masalah.

Bagaimana saya bisa menerapkan ini untuk mengembalikan kedua perintah jika salah satu dari mereka memiliki kesalahan dalam eksekusi?

Jawaban:


513

Tambahkan blok coba / tangkap, jika transaksi berhasil maka akan melakukan perubahan, jika transaksi gagal transaksi dibatalkan:

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
Bukankah BEGIN TRANSACTION [Tran1]seharusnya ditempatkan di dalam TRY? Pokoknya - sepotong kode yang sangat sederhana dan elegan.
Piotr Nawrot

4
@PiotrNawrot Tidak, jika kreasi transaksi gagal, tidak perlu mengembalikannya.
Monsinyur

114

Pada awal prosedur tersimpan, seseorang harus menempatkan SET XACT_ABORT ON untuk menginstruksikan Sql Server untuk secara otomatis mengembalikan transaksi jika terjadi kesalahan. Jika ommited atau diatur ke OFF, seseorang perlu menguji @@ ERROR setelah setiap pernyataan atau menggunakan ... COCH blok rollback .


2
Dengan kata lain, transaksi Anda tidak bersifat atomik kecuali Anda SET XACT_ABORT AKTIF dulu.
4AM

Sulit untuk melihat dengan url yang digarisbawahi, tetapi ada garis bawah diXACT_ABORT
BurnsBA

32

Pendekatan mudah:

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;
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.