Không SAVE TRANSACTION
. Tôi chưa bao giờ tìm thấy một trường hợp cho việc sử dụng này. Tôi biết một số người thích nó, nhưng trong tất cả mọi thứ tôi đã từng làm ở bất kỳ nơi nào tôi đã làm việc, khái niệm về lỗi xảy ra trong bất kỳ cấp độ lồng nhau nào đều ngụ ý rằng bất kỳ công việc nào đã được thực hiện đều không hợp lệ. Bằng cách sử dụng, SAVE TRANSACTION
bạn chỉ quay trở lại trạng thái ngay trước khi Thủ tục được lưu trữ này được gọi, để lại quy trình hiện tại như hợp lệ.
Nếu bạn muốn biết thêm chi tiết SAVE TRANSACTION
, xin vui lòng xem thông tin trong câu trả lời này:
Cách khôi phục khi 3 thủ tục được lưu trữ được bắt đầu từ một thủ tục được lưu trữ
Một vấn đề khác SAVE TRANSACTION
là một sắc thái của hành vi của nó, như đã lưu ý trong trang MSDN cho SAVE TRANSACTION (nhấn mạnh thêm):
Tên điểm lưu trữ trùng lặp được cho phép trong một giao dịch, nhưng câu lệnh ROLLBACK TRANSACTION chỉ định tên điểm lưu trữ sẽ chỉ đưa giao dịch trở lại Giao dịch TIẾT KIỆM gần đây nhất bằng cách sử dụng tên đó.
Có nghĩa là, bạn cần hết sức cẩn thận để cung cấp cho mỗi Điểm lưu trong mỗi Quy trình được lưu trữ một tên duy nhất trên tất cả các Điểm lưu trong tất cả các Quy trình được lưu trữ. Các ví dụ sau minh họa điểm này.
Ví dụ đầu tiên này cho thấy những gì xảy ra khi bạn sử dụng lại tên Save Point; chỉ Điểm lưu trữ cấp thấp nhất được khôi phục.
IF (OBJECT_ID(N'tempdb..#SaveTranTestA') IS NOT NULL)
BEGIN
DROP TABLE #SaveTranTestA;
END;
CREATE TABLE #SaveTranTestA (SomeVal INT NOT NULL);
BEGIN TRAN; -- start level 1
SAVE TRANSACTION MySavePoint;
SELECT @@TRANCOUNT AS [TranCount]; -- 1
INSERT INTO #SaveTranTestA (SomeVal) VALUES (100);
BEGIN TRAN; -- start level 2
SAVE TRANSACTION MySavePoint;
SELECT @@TRANCOUNT AS [TranCount]; -- 2
INSERT INTO #SaveTranTestA (SomeVal) VALUES (200);
COMMIT; -- exit level 2
SELECT @@TRANCOUNT AS [TranCount]; -- 1
SELECT * FROM #SaveTranTestA;
-- 100
-- 200
ROLLBACK TRANSACTION MySavePoint; -- error occurred; undo actions up to this point
SELECT @@TRANCOUNT AS [TranCount]; -- 1
SELECT * FROM #SaveTranTestA;
-- 100
COMMIT; -- exit level 1
SELECT @@TRANCOUNT AS [TranCount]; -- 0
SELECT * FROM #SaveTranTestA;
-- 100
Ví dụ thứ hai này cho thấy những gì xảy ra khi bạn sử dụng tên Save Point duy nhất; Điểm lưu trữ của cấp độ mong muốn được khôi phục.
IF (OBJECT_ID(N'tempdb..#SaveTranTestB') IS NOT NULL)
BEGIN
DROP TABLE #SaveTranTestB;
END;
CREATE TABLE #SaveTranTestB (SomeVal INT NOT NULL);
BEGIN TRAN; -- start level 1
SAVE TRANSACTION MySavePointUno;
SELECT @@TRANCOUNT AS [TranCount]; -- 1
INSERT INTO #SaveTranTestB (SomeVal) VALUES (100);
BEGIN TRAN; -- start level 2
SAVE TRANSACTION MySavePointDos;
SELECT @@TRANCOUNT AS [TranCount]; -- 2
INSERT INTO #SaveTranTestB (SomeVal) VALUES (200);
COMMIT; -- exit level 2
SELECT @@TRANCOUNT AS [TranCount]; -- 1
SELECT * FROM #SaveTranTestB;
-- 100
-- 200
ROLLBACK TRANSACTION MySavePointUno; --error occurred; undo actions up to this point
SELECT @@TRANCOUNT AS [TranCount]; -- 1
SELECT * FROM #SaveTranTestB;
-- <no rows>
COMMIT; -- exit level 1
SELECT @@TRANCOUNT AS [TranCount]; -- 0
SELECT * FROM #SaveTranTestB;
-- <no rows>