Berk Akademi
Ana Sayfa
ÖZEL KODLAMA DERSLERİ
Yazılım Özel Ders
Tüm birebir programlara genel bakış
Python Yazılım Kursu
Sıfırdan ileri seviyeye birebir Python
Java Yazılım Kursu
OOP odaklı birebir Java eğitimi
AP Computer Science Principles
AP CSP sınav hazırlığı
GRUP DERSLERİ
Python & Django Masterclass
SINIRLI KONTENJAN
Java & Spring Boot Masterclass
SINIRLI KONTENJAN
C# .NET Masterclass
SINIRLI KONTENJAN
VİDEO DERSLER
Sıfırdan Temel Python Kursu
Kendi Hızında Öğren
ÜCRETSİZ
Seviye Testi
Ücretsiz — Python, Java, algoritma seviye testleri
Kariyerini Keşfet
Sertifika Doğrula
Belge numarası ve soyad ile doğrulama

SQL Transaction ve ACID Prensipleri Nasıl Çalışır?

sql-transaction-acid-prensipleri
Bu yazıda neler var?
  1. Transaction nedir ve para transferinde neden gereklidir?
  2. ACID prensipleri para transferini nasıl güvenli tutar?
  3. BEGIN, COMMIT ve ROLLBACK ile transaction akışı
  4. İşlem yarıda kesildiğinde veri neden bozulmadan kalır?
  5. Python uygulamalarında transaction yönetiminin genel akışı
  6. Java ve JDBC tarafında transaction akışı nasıl kurulur?
  7. Sık Sorulan Sorular

SQL transaction, birbiriyle bağlantılı veritabanı işlemlerini tek bir mantıksal bütün olarak yönetir. Para transferinde işlem ya tamamen tamamlanır ya da başarısız olduğunda başlangıç durumuna dönülür; böylece bir hesaptan para düşülüp diğer hesaba eklenmeden kalmaz.

Bu güvenliğin temelinde ACID prensipleri bulunur. Atomicity, Consistency, Isolation ve Durability olarak adlandırılan bu dört özellik; transfer sırasında verinin eksilmesini, yanlış görünmesini veya uygulama kapansa bile onaylanmış işlemin kaybolmasını önlemeye yardımcı olur.

Transaction nedir ve para transferinde neden gereklidir?

Transaction, bir iş kuralını gerçekleştirmek için gereken birbiriyle bağlantılı SQL işlemlerinin tek bir işlem gibi ele alınmasıdır. Türkçede genellikle “işlem” veya “veritabanı işlemi” olarak kullanılır. Buradaki önemli nokta, transaction’ın yalnızca tek bir satırı güncellemekle ilgili olmamasıdır. Asıl amaç, birlikte anlam taşıyan birkaç adımın aynı bütünlük içinde yürütülmesidir.

Para transferi bu kavramı anlamak için iyi bir örnektir. A hesabından B hesabına 500 TL gönderildiğini düşünelim. Bu iş kuralı en az iki veritabanı adımından oluşur:

  1. A hesabının bakiyesinden 500 TL düşülür.
  2. B hesabının bakiyesine 500 TL eklenir.

Bu iki güncelleme ayrı ayrı düşünüldüğünde her biri teknik olarak başarılı görünebilir. Ancak transferin anlamlı olabilmesi için ikisinin birlikte gerçekleşmesi gerekir. Sadece A hesabından para düşülür ve ardından uygulama kapanırsa B hesabına para eklenemez. Bu durumda sistemdeki toplam para 500 TL azalmış gibi görünür. Tersine, yalnızca B hesabına para eklenirse sistemde gerçekte olmayan 500 TL oluşmuş gibi görünür.

Bu nedenle bir transaction için temel cevap şudur: İşlem ya bütünüyle tamamlanmalı ya da başlangıç durumuna dönmelidir. A hesabından para düşme ve B hesabına para ekleme adımlarından biri başarısız olursa, daha önce yapılan değişiklikler geri alınmalıdır. Böylece veritabanı transfer başlamadan önceki duruma döner ve yarım kalmış bir işlem kalıcı hâle gelmez.

Transaction neden tek kayıt güncellemesinden daha geniştir?

Tek bir hesabın bakiyesini güncellemek, yalnızca bir kayıt üzerinde yapılan değişiklik gibi görülebilir. Fakat para transferinde iş kuralı iki hesabın birlikte değerlendirilmesini gerektirir. A hesabındaki azalma, B hesabındaki artışla eşleşmiyorsa işlem doğru değildir.

Buradaki bütünlük, “kaç satır güncellendi?” sorusundan çok “iş kuralının tüm adımları tamamlandı mı?” sorusuyla ilgilidir. Bir transaction şu tür adımları aynı mantıksal çerçevede tutabilir:

  • Gönderen hesabın bakiyesini azaltmak,
  • Alıcı hesabın bakiyesini artırmak,
  • Transfer kaydını oluşturmak,
  • Gerekliyse işlem durumunu başarılı olarak işaretlemek.

Örneğin A hesabının bakiyesi azaltıldığı hâlde transfer geçmişine kayıt eklenmezse, para hareketi gerçekleşmiş olsa bile sistemin denetim ve raporlama tarafı eksik kalabilir. Benzer şekilde transfer kaydı oluşturulup hesap bakiyeleri değişmezse, geçmişte başarılı görünen fakat gerçekte gerçekleşmemiş bir işlem oluşur. Transaction yaklaşımı, bu bağlantılı adımların bir bütün olarak değerlendirilmesini sağlar.

Para transferinde transaction kullanılmazsa ne olabilir?

Transaction yönetimi olmadan uygulama, SQL komutlarını sırayla çalıştırır ve her komutu birbirinden bağımsız kabul edebilir. İlk güncelleme başarılı olduktan sonra ikinci güncellemede hata oluşursa, uygulamanın ilk değişikliği otomatik olarak geri alacağı garanti edilmez.

Hata; yanlış hesap numarası, yetersiz bakiye kontrolü, veritabanı bağlantısının kesilmesi veya uygulamanın beklenmedik biçimde kapanması gibi nedenlerle ortaya çıkabilir. Sorunun kaynağı ne olursa olsun, sistemin ortasında A hesabından para düşülmüş ve B hesabı güncellenmemişse veri artık iş kuralını temsil etmiyordur.

Transaction bu riski iki temel sonuçla yönetir:

  • Tüm adımlar başarılı olursa değişiklikleri onaylar.
  • Adımlardan biri başarısız olursa önceki değişiklikleri geri alır.

Dolayısıyla transaction’ın amacı hatayı yok etmek değil, hata meydana geldiğinde veritabanını tutarlı bir durumda bırakmaktır. Transfer başarısız olabilir; ancak başarısız transfer, hesaplardan yalnızca birini değiştirmemelidir.

ACID prensipleri para transferini nasıl güvenli tutar?

ACID prensipleri para transferini nasıl güvenli tutar?

ACID, transaction davranışını açıklayan dört temel özelliğin baş harflerinden oluşur. Bu kavramlar, para transferinin yalnızca doğru SQL komutlarını çalıştırmasını değil, işlem sırasında ve sonrasında güvenilir bir sonuç üretmesini hedefler.

Harf Anlamı Para transferindeki karşılığı
A Atomicity (Bölünmezlik) A hesabından para düşme ve B hesabına para ekleme adımları birlikte başarılı olur; biri başarısızsa işlem bütünüyle geri alınır.
C Consistency (Tutarlılık) Bakiye, toplam para ve diğer iş kuralları transfer öncesinde ve sonrasında geçerli kalır.
I Isolation (Yalıtım) Aynı hesaplar üzerinde çalışan eş zamanlı işlemler, birbirlerinin henüz tamamlanmamış ara sonuçlarını görmez.
D Durability (Kalıcılık) COMMIT ile onaylanan transfer, işlem sonrasında bağlantı kesilse veya uygulama kapansa bile korunur.

Atomicity (Bölünmezlik): Transferin tamamı birlikte gerçekleşir

Atomicity, transaction’ın dışarıdan tek bir bütün gibi davranmasını ifade eder. A hesabından 500 TL düşme başarılı olup B hesabına ekleme başarısız olursa, ilk değişiklik de geri alınmalıdır. Kullanıcı açısından sonuç “yarım transfer” değil, başarısız bir transfer olmalıdır.

Bu prensipte işlem adımlarının her birinin tek başına doğru olması yeterli değildir. İki güncellemenin aynı transferin parçaları olduğu kabul edilir. Bu nedenle transaction tamamlanmadan yapılan ara değişiklikler, son kullanıcıya kesinleşmiş sonuç olarak sunulmamalıdır.

Consistency (Tutarlılık): Veritabanı kuralları korunur

Consistency, transaction tamamlandığında veritabanının tanımlı kurallara uygun kalmasıdır. Para transferinde bu kurallar; gönderen hesabın bakiyesinin izin verilen sınırların altına düşmemesi, transfer edilen tutarın alıcıya doğru miktarda yansıması ve sistemdeki toplam paranın işlem mantığına aykırı biçimde değişmemesi gibi kontrolleri kapsayabilir.

Örneğin A hesabında 300 TL varken 500 TL transfer edilmeye çalışılıyorsa, uygulama bu işlemi başarılı kabul etmemelidir. Yetersiz bakiye kontrolü geçilmeden yapılan bir düşme işlemi, sistemin iş kurallarını ihlal eder. Aynı şekilde 500 TL A hesabından düşülüp B hesabına 450 TL eklenmesi de tutarlılığı bozar; çünkü transfer edilen tutar iki hesapta eşleşmemiş olur.

Isolation (Yalıtım): Eş zamanlı işlemler ara sonucu görmez

Isolation, aynı anda çalışan transaction’ların birbirlerinin tamamlanmamış sonuçlarından etkilenmemesini amaçlar. “Eş zamanlı” ifadesi, birden fazla kullanıcının veya uygulama işleminin aynı zaman aralığında veritabanına erişmesi anlamına gelir.

Örneğin A hesabından B hesabına 500 TL transfer edilirken başka bir işlem A hesabının bakiyesini okumaya çalışabilir. Transfer henüz tamamlanmadan bu işlem, yalnızca A hesabından para düşülmüş ara durumu görürse yanlış bir bakiye bilgisi kullanabilir. Yalıtım sayesinde diğer işlem, yarım transfer sonucunu kesinleşmiş veri gibi değerlendirmez.

Bu özellik özellikle aynı hesabın kısa süre içinde birden fazla işleme konu olduğu durumlarda önemlidir. Sistem, işlemlerin birbirleriyle çakışmasını ve bir işlemin diğerinin henüz tamamlanmamış adımlarını yanlış yorumlamasını engelleyecek bir çalışma düzeni kurar.

Durability (Kalıcılık): Onaylanan sonuç kaybolmaz

Durability, transaction COMMIT ile onaylandıktan sonra sonucun kalıcı olmasını ifade eder. Para transferinde A hesabından tutar düşülmüş, B hesabına aynı tutar eklenmiş ve işlem başarılı olarak onaylanmışsa, bağlantının daha sonra kesilmesi veya uygulamanın kapanması bu sonucu ortadan kaldırmamalıdır.

Bu prensip, “işlem başarılı” mesajının yalnızca geçici bir bellekte oluşan durumu değil, veritabanına kalıcı biçimde yazılmış sonucu ifade etmesini sağlar. Kullanıcı transferin tamamlandığını gördükten sonra sistem yeniden başlatıldığında hesap bakiyeleri ve transferin sonucu aynı iş kuralını göstermelidir.

ACID prensipleri birlikte değerlendirildiğinde para transferinin güvenliği tek bir özelliğe dayanmaz. Atomicity işlemin yarım kalmasını, Consistency kuralların bozulmasını, Isolation eş zamanlı işlemlerin ara sonuçları görmesini, Durability ise onaylanmış sonucun kaybolmasını önlemeye odaklanır.

BEGIN, COMMIT ve ROLLBACK ile transaction akışı

Bir transaction, veritabanında birlikte tamamlanması gereken SQL işlemlerini tek bir işlem sınırı içinde toplar. Para transferinde bu sınır, gönderen hesabın bakiyesinden para düşülmesi ile alıcı hesabın bakiyesine para eklenmesinin aynı bütünün parçaları olmasını sağlar.

Örneklerde şu yapıya sahip bir accounts tablosu varsayalım:

  • id = 1 olan gönderen hesabın başlangıç bakiyesi: 1.000 TL
  • id = 2 olan alıcı hesabın başlangıç bakiyesi: 500 TL
  • Transfer tutarı: 200 TL

Bu durumda başarılı bir transferin sonunda gönderen hesapta 800 TL, alıcı hesapta ise 700 TL bulunmalıdır. Akışın temel komutları şunlardır:

  • BEGIN: Transaction sınırını başlatır.
  • UPDATE: Bu sınır içinde veritabanı kayıtlarını değiştirir.
  • COMMIT: Başarılı değişiklikleri kesinleştirir.
  • ROLLBACK: Onaylanmamış değişiklikleri geri alır.

Başarılı para transferinde COMMIT kullanımı

Aşağıdaki örnekte önce gönderen hesabın bakiyesi 200 TL azaltılır, ardından alıcı hesabın bakiyesi 200 TL artırılır. İki güncelleme de sorunsuz tamamlanırsa COMMIT çağrılır.

BEGIN;

UPDATE accounts
SET balance = balance - 200
WHERE id = 1;

UPDATE accounts
SET balance = balance + 200
WHERE id = 2;

COMMIT;

Bu kodun para transferindeki karşılığı adım adım şöyledir:

  1. Başlangıç durumu: Gönderen hesap 1.000 TL, alıcı hesap 500 TL bakiyeye sahiptir.
  2. Geçici değişiklik: İlk UPDATE sonrasında gönderen hesabın transaction içindeki bakiyesi 800 TL olur.
  3. Geçici değişiklik: İkinci UPDATE sonrasında alıcı hesabın transaction içindeki bakiyesi 700 TL olur.
  4. COMMIT: Her iki güncellemenin de başarılı olduğu onaylanır ve değişiklikler kesinleştirilir.
  5. Gözlenen sonuç: Gönderen hesabın bakiyesi 800 TL, alıcı hesabın bakiyesi 700 TL olarak kalır.

Buradaki önemli nokta, ilk UPDATE komutunun tek başına transferi tamamlamamasıdır. Para gönderen hesaptan düşülmüş olsa bile alıcıya eklenmeden işlem tamamlanmış sayılmaz. COMMIT, iki adımın birlikte başarılı olduğunu veritabanına bildirir.

Hata tespit edildiğinde ROLLBACK kullanımı

İkinci senaryoda başlangıç bakiyeleri yine aynıdır: gönderen hesap 1.000 TL, alıcı hesap 500 TL’dir. Uygulama, 200 TL’lik transferin ilk adımını gerçekleştirir; ancak ikinci adımda alıcı hesabın beklenen koşulları sağlamadığını veya ilgili kaydın bulunamadığını tespit eder. Bu durumda işlem onaylanmadan ROLLBACK çağrılır.

BEGIN;

UPDATE accounts
SET balance = balance - 200
WHERE id = 1;

-- Hata tespit edildi:
-- Alıcı hesap doğrulanamadı, ikinci UPDATE çalıştırılmıyor.

ROLLBACK;

Bu senaryonun akışı şu şekilde ilerler:

  1. Başlangıç durumu: Gönderen hesap 1.000 TL, alıcı hesap 500 TL bakiyeye sahiptir.
  2. Geçici değişiklik: İlk UPDATE transaction içinde gönderen hesabın bakiyesini 800 TL’ye düşürür.
  3. Hata tespiti: Uygulama, transferin devam etmesini engelleyen bir durum algılar. Örneğin alıcı hesabın doğrulanamaması veya beklenen hesabın bulunamaması gibi bir iş kuralı hatası oluşur.
  4. ROLLBACK: Henüz kesinleşmemiş 200 TL’lik düşüş geri alınır.
  5. Gözlenen sonuç: Gönderen hesap yeniden 1.000 TL, alıcı hesap ise 500 TL olarak görülür.

Bu örnekte transaction içindeki geçici değer ile transaction sonrasındaki gözlenen değer birbirinden ayrılır. İlk UPDATE çalıştığında işlem kapsamı içinde 800 TL görülse de ROLLBACK sonrasında bu değişiklik kalıcı olmaz. Böylece para gönderen hesaptan düşülmüş, fakat alıcıya aktarılmamış bir ara durum veritabanında kesinleşmez.

İşlem yarıda kesildiğinde veri neden bozulmadan kalır?

İşlem yarıda kesildiğinde veri neden bozulmadan kalır?

Para transferi gibi işlemlerde veri bozulması genellikle iki adımın yalnızca birinin tamamlanmasıyla ortaya çıkar. Gönderen hesabın bakiyesi azalırken alıcı hesabın bakiyesi artmazsa sistemde para kaybı varmış gibi görünür. Transaction yaklaşımı, değişiklikleri tek tek bağımsız sonuçlar olarak değil, birlikte tamamlanması gereken tek işlem olarak ele alır.

Ancak burada “transaction yarıda kesilirse her veritabanı her durumda otomatik olarak geri alır” şeklinde evrensel bir varsayım yapılmamalıdır. Bağlantı davranışı, kullanılan sürücü, autocommit ayarı ve veritabanı yönetim sisteminin transaction uygulaması sonucu etkileyebilir. Uygulama, özellikle bir iş kuralı hatası tespit ettiğinde açıkça ROLLBACK çağıracak şekilde tasarlanmalıdır.

Yetersiz bakiye durumunda ne olur?

Gönderen hesabın bakiyesi transfer tutarından düşükse işlem devam etmemelidir. Örneğin gönderen hesapta 1.000 TL varken 1.200 TL gönderilmeye çalışılırsa bu durum bir iş kuralı hatasıdır. SQL söz dizimi doğru olsa bile uygulamanın transferi reddetmesi gerekir.

Bu durumda güvenli akış şu mantığa dayanır:

  1. Gönderen hesabın bakiyesi okunur.
  2. Mevcut bakiyenin transfer tutarını karşılayıp karşılamadığı kontrol edilir.
  3. Yetersiz bakiye varsa transfer adımları uygulanmaz veya açık transaction ROLLBACK ile sonlandırılır.
  4. Kullanıcıya işlemin neden tamamlanmadığı bildirilir.

Yetersiz bakiye kontrolünün yalnızca kullanıcı arayüzünde yapılması yeterli değildir. Aynı kontrol, veritabanı işlemini yürüten uygulama akışında da bulunmalıdır. Çünkü farklı bir istemci veya eş zamanlı başka bir işlem aynı hesabı değiştirebilir.

SQL hatası oluştuğunda ne olur?

Bir UPDATE komutunda yanlış sütun adı, geçersiz veri türü, bulunamayan tablo veya kısıt ihlali gibi bir hata oluşabilir. Örneğin gönderen hesabın bakiyesi güncellenmiş, ancak alıcı hesaba yapılan ikinci güncelleme veritabanı hatası nedeniyle başarısız olmuş olabilir.

Bu durumda uygulama hatayı yakalamalı ve transaction hâlâ açık ise ROLLBACK çalıştırmalıdır. Böylece ilk güncellemenin tek başına kalıcı hâle gelmesi engellenir. Amaç, transferin ya tamamen tamamlanması ya da başlangıç durumuna dönmesidir.

COMMIT öncesinde bağlantı koparsa ne olur?

Uygulama ile veritabanı arasındaki bağlantı, iki UPDATE tamamlanmadan veya COMMIT çağrılmadan kopabilir. Bu durumda değişikliklerin kalıcı olup olmayacağı; kullanılan bağlantı sürücüsüne, autocommit yapılandırmasına ve veritabanı sisteminin bağlantı kopması karşısındaki davranışına bağlıdır.

Bu nedenle uygulama kodu, bağlantı kopmasını yalnızca “veritabanı zaten geri almıştır” varsayımıyla ele almamalıdır. Hata yakalanmalı, bağlantının ve transaction durumunun ne olduğu kontrol edilmeli, yeniden deneme veya kullanıcıya hata bildirme stratejisi belirlenmelidir. COMMIT başarıyla tamamlanmadan işlem kesinleşmiş kabul edilmemelidir; ancak kesin davranış için kullanılan teknoloji yığını ayrıca incelenmelidir.

Atomicity ve Durability ilişkisi

Atomicity, transaction içindeki işlemlerin bölünmez bir bütün gibi davranmasını ifade eder. Para transferinde gönderen hesaptan düşme ve alıcı hesaba ekleme adımlarından biri başarısız olursa, diğer adımın tek başına kalıcı hâle gelmemesi beklenir.

Durability ise başarılı biçimde COMMIT edilen değişikliklerin sistemde kalıcı olmasını anlatır. Transfer başarıyla onaylandıktan sonra uygulama kapanırsa veya yeni bir bağlantı kurulursa, veritabanı transferin kesinleşmiş sonucunu korumalıdır.

Bu iki prensip farklı sorulara yanıt verir:

  • Atomicity: İşlem yarıda kalırsa parçalı sonuç oluşmasını nasıl önler?
  • Durability: İşlem başarıyla onaylandıktan sonra sonucu nasıl korur?

Transaction hata teşhis kontrol listesi

Para transferi beklenenden farklı sonuçlandığında aşağıdaki sorular, sorunun hangi aşamada oluştuğunu anlamaya yardımcı olur:

  • COMMIT çağrıldı mı? Çağrılmadıysa değişiklikler kesinleşmemiş olabilir.
  • İş kuralı doğrulandı mı? Yetersiz bakiye, geçersiz hesap veya izin problemi işlemden önce ya da işlem sırasında kontrol edildi mi?
  • Hata yakalandı mı? SQL hatası, bağlantı hatası veya sürücü kaynaklı istisna uygulama tarafından ele alındı mı?
  • ROLLBACK çalıştı mı? Hata sonrasında açık transaction geri alındı mı?
  • Autocommit ayarı nedir? Her SQL komutunun otomatik kesinleşmesine neden olan bir bağlantı ayarı bulunuyor mu?
  • İki hesap da kontrol edildi mi? Gönderen ve alıcı hesapların son bakiyeleri aynı transaction sonucu üzerinden incelendi mi?

Bu kontrol listesi, “para gitti ama karşı hesaba ulaşmadı” gibi görünen durumlarda incelemeyi rastgele yapmak yerine transaction sınırına, hata yönetimine ve kesinleştirme adımına odaklar. Güvenli bir transfer akışında temel hedef, başlangıç durumu ile gözlenen sonuç arasında yalnızca açıkça onaylanmış bir değişiklik bırakmaktır.

Python uygulamalarında transaction yönetiminin genel akışı

Python tarafında transaction yönetiminin temel mantığı, veritabanı işlemlerini tek bir bütün olarak ele almaktır. Para transferinde gönderen hesaptan para düşülüp alıcı hesaba eklenmeden önce bir hata oluşursa, ilk değişiklik kalıcı hâle getirilmemelidir. Bu nedenle uygulama; sorguları try bloğunda çalıştırır, her şey başarılıysa commit() çağırır, hata oluşursa rollback() ile işlemleri geri alır ve bağlantıyı finally bölümünde kapatır.

Bu akışta transaction sınırı, “para transferi başladı” ile “transfer başarıyla tamamlandı” arasındaki bölümdür. Gönderen hesabın bakiyesi azaltıldığı hâlde alıcı hesabına para eklenemezse, sistem yalnızca ilk sorgunun kalıcı olmasına izin vermemelidir. Günlük hayatta bir bankacının iki kaydı aynı dosyanın parçası olarak güncellemesi buna benzer: Dosyanın yalnızca yarısı tamamlanmış kabul edilmez.

Aşağıdaki örnek, transaction akışını göstermek için hazırlanmış kısa bir Python iskeletidir. sqlite3 kullanılsa da amaç belirli bir kütüphane veya sürüm özelliğini öğretmek değil; farklı veritabanı bağlantılarında da kullanılan genel try, commit, rollback ve finally düşünce modelini göstermektir.

import sqlite3

connection = sqlite3.connect(":memory:")
connection.execute("CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)")
connection.executemany("INSERT INTO accounts VALUES (?, ?)", [(1, 1000), (2, 500)])

try:
    amount = 300
    sender_balance = connection.execute(
        "SELECT balance FROM accounts WHERE id = ?", (1,)
    ).fetchone()[0]

    if sender_balance < amount:
        raise ValueError("Yetersiz bakiye")

    connection.execute("UPDATE accounts SET balance = balance - ? WHERE id = ?", (amount, 1))
    connection.execute("UPDATE accounts SET balance = balance + ? WHERE id = ?", (amount, 2))
    connection.commit()
    print("Transfer tamamlandı.")
except Exception as error:
    connection.rollback()
    print("Transfer geri alındı:", error)
finally:
    connection.close()

Örnekte önce gönderen hesabın bakiyesi okunur. Bakiye yeterliyse iki UPDATE sorgusu çalıştırılır: İlk sorgu gönderen hesaptan para düşer, ikinci sorgu alıcı hesabın bakiyesini artırır. İki sorgudan sonra commit() çağrıldığı için değişiklikler transaction kapsamında kalıcı hâle gelir.

Burada önemli bir ayrıntı vardır: Yetersiz bakiye, veritabanının sözdizimi açısından bir SQL hatası olmak zorunda değildir. Sorgu teknik olarak doğru çalışabilir; ancak para transferinin iş kuralı ihlal edilmiştir. Uygulama bu durumu kontrol ederek ValueError gibi bir istisnaya dönüştürür. İstisna except bloğuna ulaştığında rollback() çağrılır ve transaction sırasında yapılmış değişiklikler geri alınır.

  • Bağlantı açma: Uygulama veritabanına erişebileceği bir bağlantı oluşturur.
  • Transaction işlemlerini başlatma: Para transferinin parçası olan sorgular aynı akış içinde çalıştırılır.
  • İş kuralını kontrol etme: Bakiye, hesap durumu veya transfer tutarı gibi koşullar değerlendirilir.
  • Başarılı durumda commit: Tüm sorgular beklenen sonucu verirse değişiklikler kalıcılaştırılır.
  • Hata durumunda rollback: SQL hatası veya uygulama tarafından üretilen iş kuralı istisnası sonrasında değişiklikler geri alınır.
  • Kaynağı kapatma: Bağlantı, hata oluşsa da oluşmasa da kapatılır.

finally bloğunun görevi transaction sonucuna karar vermek değildir. Bu karar commit() veya rollback() çağrılarıyla verilir. finally ise veritabanı bağlantısı gibi kaynakların açık kalmasını önler. Bağlantının kapatılmaması; küçük bir betikte fark edilmese bile uzun süre çalışan uygulamalarda kaynak tüketimine, bağlantı havuzunun dolmasına veya yeni işlemlerin başlatılamamasına yol açabilir.

Gerçek uygulamalarda transfer fonksiyonu çoğunlukla bağlantıyı kendisi oluşturmaktan ziyade dışarıdan verilen bir bağlantıyı kullanır. Böylece bağlantı havuzu, loglama, test ortamı ve hata yönetimi daha kontrollü biçimde tasarlanabilir. Ancak temel düşünce değişmez: Transferin iki tarafı aynı transaction sınırı içinde yürütülmeli ve yalnızca bütün adımlar tamamlandığında onaylanmalıdır. Bu düşünceyi Python öğrenme sürecinde uygulamayla pekiştirmek isteyenler, Python ile veritabanı mantığını birlikte çalışabileceği birebir dersleri değerlendirebilir.

Java ve JDBC tarafında transaction akışı nasıl kurulur?

Java ve JDBC tarafında transaction yönetimi, Python’daki akışla aynı temel düşünceye dayanır. JDBC, Java uygulamasının ilişkisel veritabanıyla iletişim kurmasını sağlayan standart bir arayüzdür. Buradaki kritik nokta, tek tek SQL komutlarını çalıştırmak değil; para transferinin bütün sorgularını aynı bağlantı ve aynı transaction sınırı içinde yönetmektir.

İlk adımda bağlantının otomatik onay davranışı kapatılır. Otomatik onay açıkken her sorgu kendi başına kalıcı hâle gelebileceği için gönderen hesaptan para düşüldükten sonra alıcı hesabı güncelleyen sorgu başarısız olsa bile ilk değişiklik korunabilir. Bu nedenle uygulama, transaction’ın ne zaman başlayıp ne zaman tamamlanacağını kendisi yönetmelidir.

JDBC akışı genel olarak şu sırayı izler:

  1. Veritabanı bağlantısı alınır.
  2. Otomatik commit davranışı kapatılır.
  3. Gönderen hesabın bakiyesi kontrol edilir.
  4. Bakiye yeterliyse para gönderen hesaptan düşülür.
  5. Aynı bağlantı üzerinden alıcı hesabın bakiyesi artırılır.
  6. Tüm adımlar başarılıysa commit() çağrılır.
  7. Bir hata veya iş kuralı ihlali oluşursa rollback() çağrılır.
  8. Bağlantı ve kullanılan kaynaklar kapatılır.

Kavramsal bir JDBC iskeleti şu şekilde düşünülebilir:

connection.setAutoCommit(false);

try {
    // Gönderen hesabın bakiyesini kontrol et
    // Yetersizse bir istisna üret

    // Gönderen hesaptan transfer tutarını düş
    // Alıcı hesaba transfer tutarını ekle

    connection.commit();
} catch (Exception error) {
    connection.rollback();
    throw error;
} finally {
    connection.close();
}

Bu örnekte sorguların aynı connection nesnesi üzerinden çalıştırılması özellikle önemlidir. Birinci sorgu bir bağlantıda, ikinci sorgu başka bir bağlantıda yürütülürse bunlar aynı transaction’ın parçaları gibi davranmayabilir. Transferin atomik olması, yani iki hesap değişikliğinin birlikte başarılı veya birlikte başarısız olması için sorguların ortak transaction bağlamını paylaşması gerekir.

JDBC’de de yetersiz bakiye iki farklı şekilde ele alınabilir. Uygulama önce bakiyeyi okuyup yeterli değilse kendisi bir istisna üretebilir. Alternatif olarak bazı iş kuralları, SQL koşulları veya veritabanı kısıtlarıyla desteklenebilir. Hangi yaklaşım seçilirse seçilsin, uygulama bu durumu transferin başarısız olduğu bir sonuç olarak ele almalı ve rollback() çağırmalıdır.

Python ve Java arasındaki sözdizimi farklı olsa da transaction yönetimindeki karar sırası aynıdır: işlemleri grupla, sonucu kontrol et, başarıda onayla, hatada geri al. Bu nedenle yeni başlayanların yalnızca JDBC metodlarını ezberlemesi yeterli değildir. Asıl anlaşılması gereken konu, transaction sınırının nerede başlayıp hangi adımlar tamamlandığında sona ereceğidir. Java ile veritabanı çalışmalarını bu düşünce modeli üzerinden ilerletmek isteyenler, Java ve JDBC temellerini uygulamalı biçimde ele alan birebir çalışmalara göz atabilir.

Sık Sorulan Sorular

COMMIT ile ROLLBACK arasındaki temel fark nedir?

COMMIT, transaction içinde başarıyla yapılan değişiklikleri kalıcı hâle getirir. ROLLBACK ise henüz commit edilmemiş değişiklikleri geri alır. Para transferinde hem gönderen hesaptan para düşme hem de alıcı hesaba para ekleme başarılıysa commit kullanılır; adımlardan biri başarısızsa rollback uygulanır.

Her SQL sorgusu için BEGIN kullanmak gerekir mi?

Hayır. Her sorgu için ayrı ayrı BEGIN kullanmak zorunlu değildir. Transaction sınırı, birlikte başarılı veya birlikte başarısız olması gereken işlem grubuna göre belirlenir. Tek başına çalışan basit bir sorgu için veritabanı veya bağlantı ayarları transaction başlangıcını otomatik yönetebilir. Para transferi gibi birden fazla sorgunun tek işlem sayıldığı durumlarda ise transaction kapsamı açıkça ve kontrollü biçimde yönetilmelidir.

Yetersiz bakiye bir SQL hatası mı yoksa uygulama kuralı mıdır?

Yetersiz bakiye çoğu durumda bir uygulama kuralıdır. SQL sorgusunun yazımı doğru olabilir; ancak transfer koşulu sağlanmadığı için işlem devam ettirilmemelidir. Uygulama bu durumu istisnaya dönüştürerek except veya catch akışına sokabilir ve ardından rollback uygulayabilir.

COMMIT işleminden önce bağlantı koparsa ne olur?

Bağlantı commit tamamlanmadan koparsa transaction içindeki değişikliklerin kalıcı olup olmayacağı kullanılan veritabanının transaction garantilerine ve kopmanın hangi aşamada gerçekleştiğine bağlıdır. Genel beklenti, commit tamamlanmadıysa transaction’ın tamamlanmamış kabul edilmesi ve değişikliklerin kalıcı hâle gelmemesidir. Uygulamalar bu nedenle bağlantı hatalarını yakalamalı, sonucu belirsiz işlemleri kontrol etmeli ve gerekirse güvenli bir yeniden deneme stratejisi uygulamalıdır.

Autocommit açıkken ROLLBACK neden beklenen sonucu vermeyebilir?

Autocommit açıkken her sorgu tamamlandığında otomatik olarak onaylanabilir. Böyle bir durumda rollback çağrıldığında geri alınabilecek bekleyen değişiklik kalmamış olabilir. Örneğin gönderen hesaptan para düşme sorgusu otomatik commit edildiyse, daha sonra alıcı hesabı güncelleyen sorgu başarısız olduğunda yalnızca ikinci adımı geri almak mümkün olabilir. Birlikte yönetilmesi gereken işlemlerde autocommit davranışının bilinçli şekilde düzenlenmesi gerekir.

Transaction yönetiminin özü, veritabanına gönderilen komutlardan çok bu komutların hangi işlem bütününe ait olduğunu doğru belirlemektir.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin — Yazılım Geliştirici ve Eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; bugün öğrencinin seviyesine ve hedefine göre şekillenen sürdürülebilir öğrenme sistemleri tasarlıyor. 500'den fazla kişiye ezber değil, düşünerek kod yazmayı öğretti — Berk Akademi'de izlemeye değil üretmeye dayalı öğrenme kültürünü o kuruyor.

WhatsApp Hemen Ara