Makale Özeti

Veri erişiminde en sık kullanılan teknolojilerden birisi olan Transactionlar ve ADO.NET ile kullanımları

Makale

ADO .NET İle Transaction Base Veri Tabanı İşlemleri  - 1

       İş uygulamalarında ve özellikle veri tabanı işlemlerinde; yapılan işlemlerin tutarlı olması istenir. Bu sebeble birden fazla alt işlemin ardışıl ve tutarlı olarak yapılmasının gerektiği durumlarda "transaction lar" yoğun olarak kullanılır. Bu anlamda, bir transaction; bir işin yapılması için gerekli olan tüm alt işlemlerin gruplanmasını sağlayan bir, programlama kavramıdır.

       Bu soyut açıklamayı somutlaştırmak adına şu klasik örnekle devam edelim. Bir bankacılık uygulamasında; bir kişinin hesabından alınan bir miktar paranın, diğer bir kişinin hesabına aktarılması (havale edilmesi) durumunu incelersek; örneğin A isimli şahsın hesabından çekilen miktarın, B isimli şahsın hesabına hatasız olarak ekleninceye kadar, bakiye değişikliklerin veri tabanına yansıtılmaması gerekir. Çünkü burada yapılan iki alt işlemin gerçekleşmesi sürecinde oluşabilecek bir hata, ciddi bir tutarsızlığın nedeni olacaktır.

       Havale miktarını A isimli şahsın hesabından çektiğimizi ve bakiyenin son halini hemen o anda veri tabanında güncellediğimizi, daha sonra oluşan bir hata nedeni ile (elektrik kesilmesi yada başka bir nedenle) bu havale miktarını B nin hesabına ekleyemeden çıkmak zorunda kaldığımızı farzedelim. Bu durumda, kayıtlarda bir havale işlemi gerçekleşmiş gibi gözüküyor olmasına rağmen, gerçekte havale işlemini gerçekleştirememiş oluruz. Üstelik A nın hesabından düştüğümüz havale miktarını, B nin hesabına ekleyemediğimiz için ciddi sorunlarla karşılaşmamız kaçınılmazdır.

       Bu nedenlerden ötürü, iş uygulamalarında, yapılması gereken bir iş, mantıksal alt işlemlerine bölünerek, bir transaction şeklinde tasarlanır. Transaction kavramında ana ilke; ya hep yada hiç tir. Yani transaction olarak tasarlanmış bir işin alt işlemlerinin gerçekleşmesi sürecinde ya tüm alt işlemler doğru olarak yapılır yada -herhangi birisinde bir aksilik olması durumunda- o ana kadar yapılmış olan tüm alt işlemler de iptal edilerek, işin sonuçlanması engellenir. Bu sayede tutarsızlıkların, oluşmasının önlenmesi sağlanır.

        Örneğin bu havale işlemini bir transaction şeklinde düşünürsek, havale işleminin, alt işlemleri : havale yapılan hesaptan, havale miktarının düşülmesi ve diğer hesaba eklenmesidir.  Veri tabanında yapılacak bakiye güncelleme işlemleri ise bu transaction ının tümü ile ve hatasız olarak gerçekleşmesinin ardından yapılacaktır (commit). Alt işlemlerden birinde bir hata oluşması durumunda ise (varsa yapılmış olan diğer alt işlemde iptal edilerek) transaction durdurulacaktır (rollback). Bu sayede veri tabanında herhangi bir tutarsızlık oluşamaz.


ADO .NET İle Transaction ların Yaratılması Ve Kullanılması

       ADO .NET te bir transaction ını temsil etmeye ve yönetmeye yarayan nesne SQLTransaction yada OleDBTransaction türündendir. (ADO .NET te farklı veri kaynakları üzerinde işlem yapmak için iki farklı managed provider olduğunu hatırlayınız !)

        ADO .NET te bir transaction ının başlatılmasından ise connection nesnesinin BeginTransaction() metodu sorumludur. Prototipleri :

[Visual Basic]

Overloads Public Function BeginTransaction() As OleDbTransaction

Overloads Public Function BeginTransaction() As SQLTransaction

[C#]

public OleDbTransaction BeginTransaction();

public SQLTransaction BeginTransaction();

         Bu metodlar; IsolationLevel sembolik sabiti türünden tanımlanmış 6 farklı parametre alabilen overload fonksiyonlar olarak tasarlanmıştır.Alabileceği değerler :

ReadCommited, ReadUncommited, Chaos, RepeatableRead, Serializable,Unspecified değerleridir. Bu değerlerin ne anlama geldiğini daha sonra anlatacak olmakla beraber metoda parametre aktarımı yapılmaması durumunda ReadCommited ın default olarak atanacağını söylemem gerekir.

         Fonksiyonun dönüş değeri ise OleDbTransaction yada SQLTransaction türünden nesne referansıdır. Fonksiyondan dönen bu değer kullanılarak OleDbTransaction yada SQLTransaction türünden tanımlanmış bir transaction nesnesi türetilebilir. Örneğin;

Dim oCnn As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=XXX.mdb")

Dim oTrs As OleDb.OleDbTransaction

oCnn.Open()

oTrs = oCnn.BeginTransaction(IsolationLevel.ReadCommitted) gibi.

     Bu şekilde yaratılan ve türetilen bir nesne kullanılarak bir transaction yönetilebilir.

OleDbTransaction Yada SQLTransaction Sınıfının Bazı Üyeleri

Commit() Metodu : Bir transaction da tanımlanmış tüm alt işlemler hatasız olarak sonuçlandığında yapılan işlemleri veri tabanına yansıtır.

Rollback() Metodu : Bir transaction da tanımlanmış alt işlemlerden birinin hatalı olması durumunda (varsa yapılmış olan diğer alt işlemleri de iptal ederek) transaction ı durdurur.

Begin() Metodu : Çalışması başlatılmış olan bir transaction içerisinde başka bir "alt transaction" başlatır.

Connection Property si : Transaction nesnesini o an aktif olan bir connection nesnesi ile ilişkilendirmekte kullanılır.

IsolationLevel Property si : Transaction a ait isolation düzeyini  belirlemekte kullanılır.


Örnek Uygulama

     Amacım sadece ADO .NET ile transaction base işlemlerin nasıl yapıldığını anlatmak olduğu için içerik olarak anlaşılması kolay bir örnek hazırladım. Örneği gerçekleştirmek için sadece bir Console Application projesi başlatmanız yeterli olacak. Örnek için hazırladığım veri tabanının yapısı ise şöyle;

Musteriler Tablosu
MusteriID Isim
1 Aykut
2 Mustafa
3 Cihan
4 Taner
5 Mehmet
Borclar Tablosu
MusteriID

Borcu

1

50000

2

12000

3

470000

4

4800

5

9200

      Musteriler ve Borclar tabloları birbirlerine MusteriID alanı ile bire - bir ilişkilendirilmiş durumda. Örneğimizde bir transaction olarak tasarladığımız işlem; bu tablolara yeni bir müşteri kaydı ve o müşteriye ait borcu girmek. Bu iki işlemi transaction ının alt işlemleri olarak düşünebiliriz.

      Programlama tekniği açısından, transaction işlemleri bir hata yakalama bloğu içine entegre edilerek yazılırlar. Transaction ının bu iki alt işleminin yapılması hata yakalama bloğunun try kısmında, hata oluşması ve işlemlerin geri alınması ise doğal olarak catch kısmında gerçekleşmektedir.  Örneğin :    

      Try

oCmd.CommandText = sSQL1

oCmd.ExecuteNonQuery()

oCmd.CommandText = sSQL2

oCmd.ExecuteNonQuery()

oTrans.Commit()

        Kodu satır satır incelersek; bir transaction olarak bu iki ekleme işleminin try kısmında yapıldığını görüyoruz. Ancak dikkat edilmesi gereken şey; ExecuteNonQuery() nin çalışmasına rağmen ekleme işleminlerinin hemen o anda veri tabanına yansıtılmaması. Ekleme işlemlerinin veri tabanına yansıtılması ise  oTrans.Commit()  satırının çalıştırılmasından sonra olacaktır. (Bu sayede bu iki alt işlemden birinde dahi hata olursa diğer alt işlem de iptal edilerek tutarsızlıklar önlenmiş olunur.)  Commit() metodu çalıştıktan sonra ise transaction hatasız tamamlandığı için değişiklikler veri tabanına yansıtılır ve akış Finally kısmına geçerek devam eder.

        Bu alt işlemlerden birinde hata olması durumunda ise akış Catch kısmına atlayarak Rollback() metodu çalıştırılır ve transaction tümü ile iptal edilir. Bu aşamada progamın akışı yine Finally kısmına geçerek devam edecektir.

       Örneğin;  Dim sSQL2 As String = "Insert Into Borclar (MusteriID, Borcu) Values (6, 36000)"  satırını,

Dim sSQL2 As String = "Insert Into Borclar (MusteriID, Borcu) Values (6)"

olarak değiştirdiğimizde borcu alanına herhangi bir değer atamadığımız için hata oluşur ve akış hemen o anda catch kısmına atlar ve Rollback() çalıştırılıp diğer işleminde iptal edilmesi sağlanır. Bu sayede borcu veri tabanına girilememiş bir müşteri kaydı oluşmaz. 

Sub Main()

Dim sSQL1 As String = "Insert Into Musteriler (MusteriID, Isim) Values (6, Umut)"

Dim sSQL2 As String = "Insert Into Borclar (MusteriID, Borcu) Values (6, 36000)"

Dim oCnn As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Transaction3.mdb")

Dim oTrans As OleDb.OleDbTransaction

Dim oCmd As OleDb.OleDbCommand

oCnn.Open() Breakpoint buraya konulabilir

oTrans = oCnn.BeginTransaction(IsolationLevel.ReadCommitted)

oCmd = New OleDb.OleDbCommand()

With oCmd

.CommandType = CommandType.Text

.Connection = oCnn

Command nesnesi ile transaction nesnesinin ilişkilendirilmesi

.Transaction = oTrans

End With

Try

İlk işlem

oCmd.CommandText = sSQL1

oCmd.ExecuteNonQuery()

İkinci işlem

oCmd.CommandText = sSQL2

oCmd.ExecuteNonQuery()

Belirlenen işlemleri gerçekleştir

oTrans.Commit()

Console.WriteLine("İşlem tamamlandı !")

Catch exc As Exception

İşlemlerden birinde hata varsa

oTrans.Rollback()

Console.WriteLine("İşlem yapılamadı !")

Finally

oCnn.Close()

End Try

End Sub

NOT : Bu yazı okuyucunun ADO .NET ile ilgili temel kavramları bildiği varsayılarak hazırlanmıştır.

Aykut TAŞDELEN / XProjecTT

aykuttasdelen@hotmail.com