ADO.NET Transaction İşlemi – III (Savepoint)

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'.

ADO.NET Transaction İşlemi – III (Savepoint)” üzerine bir düşünce

  1. Cem

    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?

    Cevapla
  2. Ahmet Kaymaz Yazar

    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.

    Cevapla

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Time limit is exhausted. Please reload CAPTCHA.