Transaction Nedir, Nasıl Kullanılır?

Çoğu zaman bir transaction yalnızca bir türde işlem yapar, yani sadece veri silme, veri güncelleme veya veri ekleme gibi tek türde işlem yapar. Ama bir transaction içinde birden fazla da işlem yapılabilir. Yine transaction içinde SELECT işlemleri de yapılabilmektedir. Peki bunlar bizim bildiğimiz şeyler, neden transaction çıktı ki birden dediğinizi duyar gibiyim.

Burada dikkat edilecek nokta, transaction var çünkü, transaction içinde yer alan tüm işlemler veritabanı server üzerinde yapılmak zorunda, aksi halde transaction içindeki işlemlerin tek bi adımı dahi başarısız olsa, tüm yapılan işlemler yapılmamış gibi eski haline döner. Peki bunun yararı nedir?

Şimdi çok klasik olacak ama tabiri caizse cuk diye oturan bir örnek olduğu için :) ATM örneğini vermek istiyorum bende. Bir kullanıcı olarak ATM’ye gittiniz diyelim, yapmak istediğiniz işlem para çekmek olsun. Kartınızı taktınız, şifrenizi girdiniz, para çekmeyi seçtiniz, miktarı belirlediniz ve çekmek istiyorum dediniz. ATM arka planda tüm bu işlemleri yaptı, çekmek istediğiniz para miktarını kontrol etti, paranın var olduğunu gördü, paranızı size vermek üzere para çekilecek alana yansıttı. Kartınızı da daha önceden verdi (artık genelde önce kart, sonra para veriliyor çünkü, parayı unutma ihtimali daha az mantığı ile bakılıyor olaya) Bu esnada arka planda hesabınızdan bu miktar düştü. Para şimdi parayı alacağınız alanda ama olduki dalgınlık oldu, hemen alamadınız bir kaç saniye geçti ve bankamatikte güvenlik icabı bu parayı geri aldı. Yani parayı hesaptan çektiniz ama elinize alamadınız para geri gitti :) eee ne olacak şimdi, benim hesabımdaki para azalacak mı? Ben parayı almadım ki daha :)

İşte burada Transaction işleminin önemi devreye giriyor. Kullanıcı parasını alamadığı için Transaction sonlanmamış olur ve her şeyi eski haline geri çevirir. Yani çekilen miktar tekrar kullanıcının hesabına geri döner. Transaction işleminin önemi budur. Aynı durumu bankaya para yatıran bir şahıs içinde düşenebilirsiniz. Banka önce yatırılacak miktarı sorar, sonra kullanıcıdan parayı ister, tüm işlemler sonlandığında yani en son onay alındığında işlem aslında tamamlanmış olur.

Bildiğiniz üzere SQL Server’da default transaction türü “Auto Commit” dir. Yani yapılan işlemler anında kalıcı hale getirilir. Bu durumun avantajları olduğu gibi dez avantajları da vardır. Örneğin yapılan bir işlem sonucunda bir hata olursa ya da bu işlemi takip eden işlem hata alırsa veri tabanında verilerde uyuşmazlıklar meydana gelecektir.

Şimdi bir transaction nasıl oluşturulur buna değinelim. Bir transaction içinde yer alan tablolar ile alakalı işlem yapılırken kullanılan bu tablolar başka sorgular içinde kullanılmasın diye ilgili transaction çalışması bitene kadar kilitlenirler. SQL Server otomatik olarak bu işi yapar. Bir transaction oluşturmak için söz dizimi aşağıdaki gibidir. TRAN veya TRANSACTION her iki ifade de kullanılabilir.

BEGIN TRAN veya TRANSACTION
durum1
durum2
COMMIT TRAN veya TRANSACTION
 

Transaction Scope

Bir transaction’ın başlangıcından bitişine kadar olan aralıktır.

Transaction Türleri

Explicit Transactions

BEGIN, COMMIT, ROLLBACK komutlarıyla transactionların kontrol edilmesidir.

Bir transaction kapatılana kadar (coomit,rollback durumuna kadar), Transaction boyunca mevcut bağlantıda yapılan herşey, bu transaction içerisinde gerçekleştirilmiş sayılır.
 
Örneğin siz bir transaction açtınız, sonra bir kayıt eklediniz. Sonra başka bir tabloyu sildiniz. 2 dk sonra commit ettiniz. Bu durumda yaptığınız işlemler ancak commit veya rollback komutunu gördüğü anda kalıcı hale getirilecektir.
 
AutoCommit Transactions

Yapılan işlemin anında ve kalıcı olarak sisteme yansıtılmasıdır. Hata durumunda rollback otomatik gerçekleşir. Sql Server default olarak bu yapıyı kullanır.

Imlicit Transactions

Mevcut transaction biter bitmez(commit,rollback) yenisinin açılmasıdır. Oracle veri tabanında default yapı budur.

Not: Bir transaction açıldığı zaman, transaction scope içerisinde değişiklik gören kayıtlar var ise bu kayıtlar “lock” durumuna alınır. Aksini belirtmediğiniz sürece transaction bitene kadar başka bir kullanıcı bu kayıtlara ulaşamaz, okuyamaz,üzerinde değişiklik yapamaz.

İç İçe Transactionlar(Nested Transactions)

Bazı durumlarda bir transaction scope sonlanmadan bu scope içerisinde yeni bir transaction oluşturabilirsiniz
 
    BEGIN tran xyz
     
    DELETE FROM orders WHERE OrderID=10248
     
    BEGIN tran abc
     
    DELETE FROM Orders WHERE OrderID=10249
     
    commit tran xyz
 

  Burada en dış transactionda yapılan Rollback veya Commit işlemi içerideki tüm transactionları da Rollback veya Commit eder.

 

  Transaction Örnek1:

BEGIN TRANSACTION
INSERT INTO dbo.demoTransaction (col1) VALUES (1);
INSERT INTO dbo.demoTransaction (col1) VALUES (2);
COMMIT TRANSACTION

  Şimdi ben bu transaction ile dbo.demoTransaction tablosunda col1 kolonuna 1 ve 2 değerlerini atıyorum. Bir bakalım olmuş mu?

Transaction Nedir, Nasıl Kullanılır?

Görüleceği üzere transaction içinde yer alan iki adet veri kaydetme işlemi gerçekleştirilmiş durumda.

Bir başka transaction yazalım.

BEGIN TRANSACTION
INSERT INTO dbo.demoTransaction (col1) VALUES (3);
INSERT INTO dbo.demoTransaction (col1) VALUES ('a');
COMMIT TRANSACTION

  Bu sorgu sonucunda aşağıdaki gibi bir mesaj alırız.

(1 row(s) affected)
Msg 245, Level 16, State 1, Line 3
Conversion failed when converting the varchar value ‘a’ to data type int.

Burada ise diyor ki, 1 satır eklendi, diğeri olmadı çünkü a değeri int tipinde bir değişken değil. Yani mesaja göre 3 değerini de eklenmiş olması gerek. Benim tablomda col1 alanı için int tipinde değişken olması gerekiyor, çünkü tbalomu oluştururken üstte de görüleceği üzere şartım bu. Ama 3 eklendi diyor bu mesajda. Bir bakalım cidden eklenmiş mi?

Transaction Nedir, Nasıl Kullanılır?

Eee hani eklenmişti, (1 row(s) affected) dedi ama bana  Şimdi biz yazımızın üstte en başlarına doğru ne dedik. Bir Transaction içindeki her işlem adımının gerçekleşmesi gerekir, adımlardan herhangi birinde dahi bir hata meydana gelse ilgili transaction içindeki tüm adımlar, diğerleri gerçekleşmiş olsa dahi iptal edilir, eski haline döner. İşte buradaki durumda bu, 3 değeri tamam uygun ancak a uymuyor, yalnız bu iki işlem adımı da tek bir transaction içinde. Dolayısı ile bu ikinci yazılan transaction çalışmıyor.

Transaction Örnek 2:

$objConnect = mssql_connect("localhost","sa","");  
$objDB = mssql_select_db("mydatabase");  
 
mssql_query("BEGIN TRAN");  
 
//**** Process 1 ****//  
$strSQL = "INSERT INTO customer ";  
$strSQL .="(CustomerID,Name,Email,CountryCode,Budget,Used) ";  
$strSQL .="VALUES ";  
$strSQL .="('".$_POST["txtCustomerID"]."','".$_POST["txtName"]."','".$_POST["txtEmail"]."' ";  
$strSQL .=",'".$_POST["txtCountryCode"]."','".$_POST["txtBudget"]."','".$_POST["txtUsed"]."') ";  
$objQuery1 = mssql_query($strSQL);  
if(!$objQuery1) {  
mssql_query("ROLLBACK");  
echo "Error Save [".$strSQL."]";  
exit();  
}  
 
//**** Process 2 ****//  
$strSQL = "INSERT INTO customer ";  
$strSQL .="(CustomerID,Name,Email,CountryCode,Budget,Used) ";  
$strSQL .="VALUES ";  
$strSQL .="('".$_POST["txtCustomerID"]."','".$_POST["txtName"]."','".$_POST["txtEmail"]."' ";  
$strSQL .=",'".$_POST["txtCountryCode"]."','".$_POST["txtBudget"]."','".$_POST["txtUsed"]."') ";  
$objQuery2 = mssql_query($strSQL);  
if(!$objQuery2) {  
mssql_query("ROLLBACK");  
echo "Error Save [".$strSQL."]";  
exit();  
}  
 
//**** Process 3 ****//  
$strSQL = "INSERT INTO customer ";  
$strSQL .="(CustomerID,Name,Email,CountryCode,Budget,Used) ";  
$strSQL .="VALUES ";  
$strSQL .="('".$_POST["txtCustomerID"]."','".$_POST["txtName"]."','".$_POST["txtEmail"]."' ";  
$strSQL .=",'".$_POST["txtCountryCode"]."','".$_POST["txtBudget"]."','".$_POST["txtUsed"]."') ";  
$objQuery3 = mssql_query($strSQL);  
if(!$objQuery3) {  
mssql_query("ROLLBACK");  
echo "Error Save [".$strSQL."]";  
exit();  
}  
 
//**** Commit Transaction ****//  
if(($objQuery1) and ($objQuery2) and ($objQuery3)) {  
mssql_query("COMMIT");  
}  
 
mssql_close($objConnect);  

Transaction Örnek 3:

 BEGIN TRY
      UPDATE dbo.Hesap SET Bakiye-=100 WHERE TCKimlikNo='23456789101'
      RAISERROR('Elektrikler Kesildi',16,2)
      UPDATE dbo.Hesap SET Bakiye+=100 WHERE TCKimlikNo='12345678910'
END TRY
BEGIN CATCH
      PRINT 'Beklenmedik bir hata olustu'
END CATCH

 

Kaynak

Yorumunuzu Ekleyin


Yükleniyor...
Yükleniyor...