Xử lý lỗi trong giao dịch
Xử lý ngoại lệ có cấu trúc sử dụng cấu trúc TRY/CATCH để kiểm tra lỗi và xử lý lỗi. Khi sử dụng xử lý ngoại lệ với giao dịch, điều quan trọng là phải đặt các từ khóa COMMIT hoặc ROLLBACK vào đúng vị trí liên quan đến khối TRY/CATCH.
Cam kết giao dịch
Khi sử dụng giao dịch với xử lý ngoại lệ có cấu trúc, hãy đặt COMMIT TRANSACTION bên trong khối TRY như trong ví dụ mã sau đây:
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO dbo.Orders(custid, empid, orderdate)
VALUES (68,9,'2006-07-12');
INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
VALUES (1, 2,15.20,20);
COMMIT TRANSACTION
END TRY
Giao dịch quay lui
Khi được sử dụng với xử lý ngoại lệ có cấu trúc, hãy đặt GIAO DỊCH QUAY LUI bên trong khối CATCH như trong ví dụ mã sau đây:
BEGIN TRY
BEGIN TRANSACTION;
INSERT INTO dbo.Orders(custid, empid, orderdate)
VALUES (68,9,'2006-07-12');
INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
VALUES (1, 2,15.20,20);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;
ROLLBACK TRANSACTION;
END CATCH;
XACT_STATE
Để tránh quay lui một giao dịch hiện hoạt, hãy sử dụng hàm XACT_STATE động. XACT_STATE trả về các giá trị sau:
| Giá trị trả về | Ý nghĩa |
|---|---|
| 1 | Yêu cầu hiện tại có một giao dịch người dùng hiện hoạt, committable. |
| 0 | Không có giao dịch đang hoạt động. |
| -1 | Yêu cầu hiện tại có một giao dịch người dùng hiện hoạt, nhưng một lỗi đã xảy ra đã gây ra giao dịch được phân loại là một giao dịch không thể chịu được. |
XACT_STATE thể được sử dụng trước lệnh QUAY LUI để kiểm tra xem giao dịch có đang hoạt động hay không.
Mã sau đây cho thấy các XACT_STATE năng đang được sử dụng trong khối CATCH để giao dịch chỉ được quay lui nếu có một giao dịch người dùng đang hoạt động.
BEGIN TRY
BEGIN TRANSACTION;
INSERT INTO dbo.SimpleOrders(custid, empid, orderdate)
VALUES (68,9,'2006-07-12');
INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty)
VALUES (1, 2,15.20,20);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;
IF (XACT_STATE()) <> 0
BEGIN
ROLLBACK TRANSACTION;
END;
ELSE .... -- provide for other outcomes of XACT_STATE()
END CATCH;