Gelişmiş veritabanı sistemleri, transaction işlemlerinde Savepoint denilen kaydetme noktaları tanımlama imkanı verir. Transaction birden fazla iş parçacığından oluştuğu için başarılı biten her iş parçacığının bitiş noktasını savepont olarak işaretlemek, özellikle karmaşık transaction işlemlerinde Rollback işleminin yükünü hafifletir. Çünkü bu durumda transaction içinde Rollback yapmak gerektiği zaman transaction, en başa geri sarılmak yerine sadece belirli bir savepoint noktasına geri döndürülür.
Transaction içerisinde bir kaydetme noktası tanımlamak için SqlConnection(veya OracleTransaction) sınıfının Save() metodu kullanılır. Bu metod, oluşturacağı savepoint’in adını string parametre olarak alır. Kaydedilmiş olan savepoint’e geri dönmek için RollBack() metoduna parametre olarak o savepoint’in adı geçilir. Transaction içerisinde herhangi bir savepoint noktasına Rollback işlemi yapıldığı zaman transaction’ın başından o savepoint’e kadar yapılan işler COMMIT edilir. Aşağıdaki örneği inceleyelim;
Dim oCnn As New SqlConnection(CnnStr) Dim sQry1 As String = "UPDATE Musteri SET AdSoyad='Ayşe Güler1' WHERE MusteriId=3" Dim sQry2 As String = "UPDATE Makale SET YanlisKolon='Ahmet Kaymaz' WHERE MakaleId=1" Dim oCmd As SqlCommand = oCnn.CreateCommand() oCnn.Open() 'Transaction nesnesi oluşturalım Dim oTrs As SqlTransaction = oCnn.BeginTransaction() 'Command nesnesini oTrs ile ilişkilendirelim oCmd.Transaction = oTrs Try oCmd.CommandText = sQry1 oCmd.ExecuteNonQuery() 'Eğer ilk query'i sorunsuz çalıştırdıysa oTrs.Save("Query1") 'Gelinen bu noktayı kaydet oCmd.CommandText = sQry2 oCmd.ExecuteNonQuery() oTrs.Commit() '1 Catch ex As Exception Console.WriteLine("HATA OLUŞTU: " + ex.Message) 'oTrs.Rollback() Tüm transaction'ı rollback eder 'Tüm transaction'ı değil "Query1" ismindeki noktaya kadar geri al oTrs.Rollback("Query1") 'Transaction "Query1" noktasında bulunmaktadır. Başından o noktaya kadar COMMIT et. oTrs.Commit() '2 Finally 'Bu örnekte sadece 2.query'de hata yapılacağını bildiğimiz için her durumda COMMIT işlemi yapılacağından üstteki 1 ve 2 olarak işaretlenmiş COMMIT satırlarını iptal edip finally bloğuna ekleyebilirdik. 'oTrs.Commit() oCmd.Dispose() oCnn.Close() End Try
SqlConnection oCnn = new SqlConnection(CnnStr); string sQry1 = "UPDATE Musteri SET AdSoyad='Ayşe Güler1' WHERE MusteriId=3"; string sQry2 = "UPDATE Makale SET YanlisKolon='Ahmet Kaymaz' WHERE MakaleId=1"; SqlCommand oCmd = oCnn.CreateCommand(); oCnn.Open(); //Transaction nesnesi oluşturalım SqlTransaction oTrs = oCnn.BeginTransaction(); //Command nesnesini oTrs ile ilişkilendirelim oCmd.Transaction = oTrs; try { oCmd.CommandText = sQry1; oCmd.ExecuteNonQuery(); //Eğer ilk query'i sorunsuz çalıştırdıysa oTrs.Save("Query1");//Gelinen bu noktayı kaydet oCmd.CommandText = sQry2; oCmd.ExecuteNonQuery(); oTrs.Commit();//1 } catch(Exception ex) { Console.WriteLine("HATA OLUŞTU: "+ ex.Message); //oTrs.Rollback(); Tüm transaction'ı rollback eder //Tüm transaction'ı değil "Query1" ismindeki noktaya kadar geri al oTrs.Rollback("Query1"); //Transaction "Query1" noktasında bulunmaktadır. Başından o noktaya kadar COMMIT et. oTrs.Commit();//2 } finally { //Bu örnekte sadece 2.query'de hata yapılacağını bildiğimiz için her durumda COMMIT işlemi yapılacağından üstteki 1 ve 2 olarak işaretlenmiş COMMIT satırlarını iptal edip finally bloğuna ekleyebilirdik. //oTrs.Commit(); oCmd.Dispose(); oCnn.Close(); }
HATA OLUŞTU: Invalid column name 'YanlisKolon'.
Transaction için save özelliği güzel, peki enterprise management studio içinde bir sorgu dizisi çakmadan önce(transaction olmadan) bir savepoint oluşturup tekrar sonunda o noktaya dönebilir miyim?
Herhangi bir transaction bloğu oluşturmadan önceki bir noktaya dönmek yani bir SavePoint oluşturmak ne yazık ki mümkün değil.