SAVE TRANSACTION
ไม่ ฉันไม่เคยพบเคสสำหรับใช้สิ่งนี้ ฉันรู้ว่าบางคนชอบมัน แต่ในทุกสิ่งที่ฉันเคยทำในสถานที่ใด ๆ ที่ฉันเคยทำงานความคิดเกี่ยวกับข้อผิดพลาดที่เกิดขึ้นภายในระดับที่ซ้อนกันใด ๆ บ่งบอกว่างานใด ๆ ที่ทำไปแล้วนั้นไม่ถูกต้อง โดยการใช้งานSAVE TRANSACTION
คุณจะคืนค่ากลับสู่สถานะก่อนที่จะเรียกขั้นตอนการจัดเก็บนี้โดยปล่อยให้กระบวนการที่มีอยู่นั้นถูกต้อง
หากคุณต้องการรายละเอียดเพิ่มเติมSAVE TRANSACTION
กรุณาลองดูข้อมูลในคำตอบนี้:
วิธีการย้อนกลับเมื่อเริ่ม 3 โพรซีเดอร์ที่เก็บไว้จากโพรซีเดอร์ที่เก็บไว้หนึ่งโพรซีเดอร์
ปัญหาอีกประการหนึ่งSAVE TRANSACTION
คือความแตกต่างของพฤติกรรมตามที่ระบุไว้ในหน้า MSDN สำหรับการบันทึกรายการ (เน้นการเพิ่ม):
ชื่อจุดบันทึกซ้ำได้รับอนุญาตในการทำธุรกรรม แต่คำสั่ง ROLLBACK TRANSACTION ที่ระบุชื่อ savepoint จะย้อนกลับการทำธุรกรรมกลับไปที่การทำธุรกรรมSAVE ล่าสุดโดยใช้ชื่อนั้น
หมายความว่าคุณต้องระมัดระวังเป็นอย่างยิ่งที่จะให้แต่ละจุดบันทึกในแต่ละขั้นตอนการจัดเก็บชื่อที่ไม่ซ้ำกันในทุกจุดบันทึกในขั้นตอนการจัดเก็บทั้งหมด ตัวอย่างต่อไปนี้แสดงให้เห็นถึงจุดนี้
ตัวอย่างแรกนี้แสดงสิ่งที่เกิดขึ้นเมื่อคุณใช้ชื่อจุดบันทึกอีกครั้ง เฉพาะจุดบันทึกระดับต่ำสุดเท่านั้นที่ย้อนกลับ
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
ตัวอย่างที่สองนี้แสดงสิ่งที่เกิดขึ้นเมื่อคุณใช้ชื่อจุดบันทึกเฉพาะ จุดบันทึกของระดับที่ต้องการนั้นย้อนกลับ
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>