Tidak ada SAVE TRANSACTION
. Saya belum pernah menemukan kasus untuk menggunakan ini. Saya tahu beberapa orang lebih menyukainya, tetapi dalam segala hal yang pernah saya lakukan di tempat saya pernah bekerja, gagasan tentang kesalahan yang terjadi di salah satu level bersarang menyiratkan bahwa pekerjaan apa pun yang sudah dilakukan tidak valid. Dengan menggunakan SAVE TRANSACTION
Anda hanya mengembalikan kembali ke negara sebelum Prosedur Disimpan ini dipanggil, meninggalkan proses yang ada sebagai dinyatakan sah.
Jika Anda ingin detail lebih lanjut SAVE TRANSACTION
, silakan lihat informasi dalam jawaban ini:
Cara mengembalikan ketika 3 prosedur tersimpan dimulai dari satu prosedur tersimpan
Masalah lainnya SAVE TRANSACTION
adalah nuansa perilakunya, sebagaimana dicatat dalam halaman MSDN untuk SIMPAN TRANSAKSI (penekanan ditambahkan):
Nama savepoint duplikat diizinkan dalam transaksi, tetapi pernyataan TRANSAKSI ROLLBACK yang menentukan nama savepoint hanya akan mengembalikan transaksi ke SAVE TRANSACTION terbaru menggunakan nama itu.
Artinya, Anda harus sangat berhati-hati untuk memberikan setiap Titik Simpan di setiap Prosedur yang Disimpan nama yang unik di semua Poin Simpan di semua Prosedur yang Disimpan. Contoh-contoh berikut menggambarkan hal ini.
Contoh pertama ini menunjukkan apa yang terjadi ketika Anda menggunakan kembali nama Simpan Poin; hanya Save Point level terendah yang diputar kembali.
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
Contoh kedua ini menunjukkan apa yang terjadi ketika Anda menggunakan nama Simpan Poin yang unik; Save Point level yang diinginkan dibatalkan.
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>