Hayır SAVE TRANSACTION
. Bunu kullanmak için hiç bir dava bulamadım. Bazı milletlerin bunu tercih ettiğini biliyorum, ama şimdiye kadar çalıştığım herhangi bir yerde yaptığım her şeyde, iç içe geçmişlerin herhangi birinde meydana gelen bir hata kavramı zaten yapılmış olan her işin geçersiz olduğunu ima etti. Kullanarak SAVE TRANSACTION
, yalnızca bu Kayıtlı Prosedür çağrılmadan hemen önceki duruma geri dönersiniz ve mevcut işlemi aksi halde geçerli bırakırsınız.
Hakkında daha fazla ayrıntı istiyorsanız SAVE TRANSACTION
, lütfen bu yanıttaki bilgilere göz atın:
Bir saklı yordamdan 3 saklı yordam başlatıldığında geri alma
Başka bir sorun, KAYDET İŞLEMİSAVE TRANSACTION
için MSDN sayfasında belirtildiği gibi davranışının bir nüansıdır (vurgu eklendi):
Bir işlemde yinelenen kayıt noktası adlarına izin verilir, ancak kayıt noktası adını belirten bir ROLLBACK TRANSACTION deyimi, işlemi yalnızca bu adı kullanarak en son KAYDETME işlemine geri döndürür .
Yani, her Saklı Yordamdaki her Kayıt Noktasına tüm Saklı Yordamlardaki tüm Kaydetme Noktaları arasında benzersiz bir ad vermek için çok dikkatli olmanız gerekir. Aşağıdaki örnekler bu noktayı açıklamaktadır.
Bu ilk örnek, Kaydetme Noktası adını yeniden kullandığınızda ne olacağını gösterir; yalnızca en düşük düzeydeki Kaydetme Noktası geri alınır.
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
Bu ikinci örnek, benzersiz Kaydetme Noktası adları kullandığınızda ne olacağını gösterir; istenen seviyenin Kaydetme Noktası geri alınır.
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>