Sử dụng đúng các giao dịch trong SQL Server


236

Tôi có 2 lệnh và cần cả hai lệnh được thực thi chính xác hoặc không có lệnh nào được thực thi. Vì vậy, tôi nghĩ rằng tôi cần một giao dịch, nhưng tôi không biết làm thế nào để sử dụng nó một cách chính xác.

Có vấn đề gì với đoạn script sau đây?

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

Các INSERTlệnh được thực thi, nhưng các UPDATElệnh có một vấn đề.

Làm thế nào tôi có thể thực hiện điều này để khôi phục cả hai lệnh nếu bất kỳ lệnh nào trong số chúng có lỗi trong thực thi?

Câu trả lời:


513

Thêm khối thử / bắt, nếu giao dịch thành công, nó sẽ thực hiện các thay đổi, nếu giao dịch không thành công, giao dịch sẽ được khôi phục:

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
Không nên BEGIN TRANSACTION [Tran1]đặt bên trong TRY? Dù sao - mảnh mã rất đơn giản và thanh lịch.
Piotr Nawrot

4
@PiotrNawrot Không, nếu việc tạo giao dịch thất bại, không cần phải khôi phục nó trong quá trình bắt.
Đức ông

114

Khi bắt đầu thủ tục được lưu trữ, bạn nên đặt SET XACT_ABORT ON để hướng dẫn Sql Server tự động phục hồi giao dịch trong trường hợp có lỗi. Nếu bị chặn hoặc được đặt thành TẮT, người ta cần kiểm tra @@ ERROR sau mỗi câu lệnh hoặc sử dụng khối rollback TRY ... CATCH .


2
Nói cách khác, giao dịch của bạn không phải là nguyên tử trừ khi bạn đặt XACT_ABORT ON trước.
4 giờ sáng

Thật khó để nhìn thấy với gạch chân url, nhưng có một dấu gạch dưới trongXACT_ABORT
BurnsBA

32

Cách tiếp cận dễ dàng:

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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.