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.

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

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.

BEGIN TRANSACTION (kısaca BEGIN TRAN) komutu Microsoft SQL Server (MSSQL) üzerinde bir işlem (transaction) başlatmak için kullanılır. Bu, bir grup SQL ifadesinin bir bütün olarak çalıştırılmasını sağlar ve her şey başarılı olursa COMMIT, başarısız olursa ROLLBACK ile tamamlanır. Bu sayede bir dizi işlem sırasında tutarlılık ve bütünlük sağlanmış 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.

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

Ş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

 

BEGIN TRAN Kullanımı

Aşağıda BEGIN TRAN, COMMIT ve ROLLBACK komutlarının nasıl kullanıldığına dair bir örnek bulunmaktadır:

BEGIN TRANSACTION; İşlem başlatılır

SQL sorguları burada yapılır
UPDATE Customers SET Balance = Balance - 100 WHERE CustomerID = 1;
UPDATE Orders SET STATUS = 'Completed' WHERE OrderID = 123;

Eğer sorgular başarılı olursa
COMMIT; İşlemi başarılı bir şekilde bitirir

Eğer bir hata olursa
ROLLBACK; Tüm değişiklikleri geri alır

 

Örnek Senaryo

Bir müşteri hesabından bir miktar para düşülmesi ve bir siparişin durumunun güncellenmesi gibi bir işlem düşünelim. Bu işlem sırasında iki adım var ve her iki adımın da başarılı olması gerekiyor. Eğer herhangi bir adım başarısız olursa, yapılan değişiklikler geri alınmalıdır.

BEGIN TRANSACTION; İşlem başlatılır

BEGIN TRY
    İlk işlem: Müşterinin bakiyesini güncelle
    UPDATE Customers
    SET Balance = Balance - 100
    WHERE CustomerID = 1;

    İkinci işlem: Sipariş durumunu güncelle
    UPDATE Orders
    SET STATUS = 'Completed'
    WHERE OrderID = 123;

    Eğer tüm sorgular başarılı olursa
    COMMIT; İşlemi onayla

END TRY
BEGIN CATCH
    Hata durumunda işlemi geri al
    ROLLBACK;
   
    Hata mesajını gösterebilir veya loglayabilirsiniz
    PRINT 'İşlem başarısız oldu. Değişiklikler geri alındı.';
END CATCH;

 

Açıklamalar
  1. BEGIN TRANSACTION:

    • Bu komut bir işlem başlatır. İşlem tamamlanana kadar yapılan değişiklikler geçici olarak tutulur.
  2. COMMIT:

    • Eğer tüm sorgular başarıyla tamamlanırsa, COMMIT komutu ile değişiklikler kalıcı hale getirilir.
  3. ROLLBACK:

    • Eğer herhangi bir hata olursa, ROLLBACK komutu tüm değişiklikleri geri alır ve veritabanı işlemden önceki durumuna döner.
  4. BEGIN TRY ve BEGIN CATCH:

    • Bu yapılar, SQL Server'da hata yönetimi için kullanılır. TRY bloğunda hata olmadan çalışan sorgular COMMIT ile tamamlanır, eğer TRY bloğunda bir hata oluşursa CATCH bloğuna geçilir ve ROLLBACK yapılır.
 
Daha Gelişmiş Örnek

Birden fazla tabloya veri ekleme işlemi:

BEGIN TRANSACTION;

BEGIN TRY
    İlk tabloya veri ekle
    INSERT INTO Customers (CustomerName, Balance)
    VALUES ('Ali Veli', 1000);

    İkinci tabloya veri ekle
    INSERT INTO Orders (CustomerID, ProductName, OrderDate)
    VALUES (SCOPE_IDENTITY(), 'Laptop', GETDATE());

    Eğer tüm işlemler başarılı olursa
    COMMIT;
    PRINT 'İşlem başarılı bir şekilde tamamlandı.';
   
END TRY
BEGIN CATCH
    Hata durumunda tüm işlemleri geri al
    ROLLBACK;
    PRINT 'Bir hata oluştu. İşlem geri alındı.';
END CATCH;

 

Önemli Noktalar:
  • SCOPE_IDENTITY(): Bu fonksiyon, bir tabloya yapılan son INSERT işleminden sonra eklenen son kimlik (ID) değerini almak için kullanılır. Bu, aynı işlem içinde başka bir tabloya ekleme yaparken kullanışlıdır.
  • GETDATE(): Şu anki tarihi ve saati almak için kullanılır.
BEGIN TRANSACTION Kullanımının Faydaları:
  • Veri Bütünlüğü: Eğer bir işlem sırasında bir hata oluşursa, tüm işlem geri alınarak verilerin tutarlı kalması sağlanır.
  • Güvenlik: Büyük ve kritik işlemler sırasında bir adımda hata olduğunda, işlemin tamamı geri alınabilir.
  • Kontrol: Birden fazla işlem yaparken her adımın başarıyla tamamlandığından emin olunmasını sağlar.

SQL işlemlerinde BEGIN TRAN yapısı, karmaşık veri güncellemeleri ve eklemeleri sırasında veritabanı bütünlüğünü korumak için kritik öneme sahiptir.

Kaynak

 

 

 

Yorumunuzu Ekleyin


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