PostgreSQL Transaction Nedir? COMMIT, ROLLBACK ve SAVEPOINT
Transaction (İşlem), veritabanında gerçekleştirilen birden fazla sorgunun tek bir mantıksal bütün olarak ele alınmasını sağlayan güvenlik mekanizmasıdır. "Ya hep, ya hiç" (All-or-Nothing) prensibiyle çalışır. İşlemler başarılıysa COMMIT komutuyla veriler kalıcı hale getirilir; eğer herhangi bir adımda hata oluşursa ROLLBACK komutuyla tüm işlemler iptal edilip veritabanı eski güvenli haline döndürülür.
Özellikle e-ticaret veya bankacılık gibi kritik sistemler geliştiriyorsanız, veri tutarlılığı (Data Integrity) her şeyden önemlidir. Bir hesaptan para düşüp diğerine yatıramadığınız bir senaryoda sistemin çökmesi kabul edilemez. İşte bu yazıda, PostgreSQL'de hayat kurtaran Transaction kavramını detaylı şekilde inceleyeceğiz. BEGIN, COMMIT, ROLLBACK ve SAVEPOINT komutlarını örneklerle açıklayacağız.
1. PostgreSQL Transaction Nedir?
Transaction, veritabanına gönderdiğiniz ardışık SQL sorgularının bir paket halinde çalıştırılmasıdır. Bu sorgu paketindeki işlemlerden biri bile başarısız olursa, paket içindeki başarılı olan diğer tüm sorgular da iptal edilir. ACID (Atomicity, Consistency, Isolation, Durability) prensiplerinin temelini oluşturur.
INSERT, UPDATE veya DELETE sorgusunu arka planda tek satırlık gizli bir transaction içinde (Auto-commit) çalıştırır.
2. Temel Transaction Komutları
BEGIN;(veyaSTART TRANSACTION;): Veritabanına yeni bir işlem bloğunun başladığını haber verir. Auto-commit özelliğini geçici olarak durdurur.COMMIT;: İşlem bloğundaki tüm sorguların hatasız çalıştığını onaylar ve verileri diske kalıcı olarak yazar.ROLLBACK;: Hata durumunda işlemi iptal eder veBEGINkomutundan önceki veritabanı haline geri döner.
3. Transaction İzolasyon Seviyeleri (Isolation Levels)
Veritabanında aynı anda (eşzamanlı) binlerce transaction çalışabilir. Bu transaction'ların birbirlerinin okuduğu veya yazdığı verilere ne kadar müdahale edebileceğini belirleyen 3 temel seviye vardır:
- READ COMMITTED (Varsayılan): Bir transaction, sadece diğer transaction'lar tarafından
COMMITedilmiş (onaylanmış) verileri görebilir. Dirty Read (Kirli okuma) engellenir. - REPEATABLE READ: Transaction başladığı andaki veritabanı anlık görüntüsünü (Snapshot) kullanır. Dışarıda başka veriler değişip onaylansa bile, bu transaction kendi içindeki okumalarda hep aynı sonucu görür.
- SERIALIZABLE: En katı (ve en yavaş) seviyedir. Tüm eşzamanlı transaction'ları sanki sırayla, arka arkaya (seri) çalışıyormuş gibi kilitler. Olası tüm veri anormalliklerini (Phantom Reads vb.) önler.
4. SAVEPOINT Nedir ve Nasıl Kullanılır?
Bazen 10 adımlık devasa bir transaction yürütürken 9. adımda bir hata alırsınız. Sırf 9. adım hatalı diye ilk 8 adımı da kaybetmek istemiyorsanız SAVEPOINT kullanmalısınız. Savepoint, transaction içine koyduğunuz "Kayıt Noktalarıdır".
BEGIN;
-- Bazı işlemler yapıldı...
SAVEPOINT adim_1_kaydi;
-- Riskli işlemler yapılıyor...
ROLLBACK TO adim_1_kaydi; -- Hata çıkarsa işlemi en başa değil, adim_1_kaydi'na kadar geri alır.
COMMIT;
5. Adım Adım Transaction Örneği (Banka Transferi)
A kişisinin B kişisine para gönderdiği bir senaryoyu canlandıralım:
BEGIN;
-- 1. Adım: A'nın hesabından parayı düş
UPDATE hesaplar
SET bakiye = bakiye - 1000
WHERE musteri = 'A_Kişisi';
-- İşi sağlama almak için kayıt noktası oluştur
SAVEPOINT bakiye_dusuldu;
-- 2. Adım: B'nin hesabına parayı ekle (Ancak B'nin hesabı kapalıysa hata verir!)
UPDATE hesaplar
SET bakiye = bakiye + 1000
WHERE musteri = 'B_Kişisi';
-- 3. Adım: Eğer 2. Adımda hata çıkarsa:
ROLLBACK TO bakiye_dusuldu;
-- Hata sonrası parayı güvenli olan C kişisine yollayalım
UPDATE hesaplar
SET bakiye = bakiye + 1000
WHERE musteri = 'C_Kişisi';
-- Her şey yolundaysa işlemi kalıcı yap!
COMMIT;
6. Two-Phase Commit (2PC) Nedir?
PostgreSQL, dağıtık veritabanı sistemlerinde (Mikroservisler arası) işlem bütünlüğünü sağlamak için İki Aşamalı Onay (2PC) mekanizmasını destekler. İşlem önce hazırlanır, diğer tüm veritabanları onay verirse kalıcı hale getirilir.
PREPARE TRANSACTION 'transfer_islemi_123';
-- Eğer her sunucu "Hazırım" derse:
COMMIT PREPARED 'transfer_islemi_123';
-- Eğer bir sunucu bile hata verirse:
ROLLBACK PREPARED 'transfer_islemi_123';
7. Sık Yapılan Transaction Hataları
- Açık Bırakmak (Idle in Transaction):
BEGINyazıpCOMMITveyaROLLBACKyazmayı unutmak. Bu durum veritabanındaki tabloları kilitler ve sistemi felç eder. - Mantık Hatası: İşlemlerden biri hata verdiğinde (Örn: Division by zero) hala
COMMITkomutunu çalıştırmaya çalışmak (PostgreSQL bunu reddedecek ve işlemi iptal edecektir). - Aşırı Uzun Transaction: Yüz binlerce satırı etkileyen UPDATE işlemlerini tek bir devasa transaction içine sokarak veritabanı kilitlerini (Lock) uzun süre işgal etmek.
8. Sık Sorulan Sorular (SSS)
COMMIT ve ROLLBACK arasındaki fark nedir?
COMMIT yapılan işlemleri veritabanına kalıcı olarak (bir daha geri alınamayacak şekilde) yazar. ROLLBACK ise transaction içindeki tüm değişiklikleri çöpe atar ve veritabanını işlemin hiç başlamadığı ilk haline döndürür.
Savepoint kullanmak performansı etkiler mi?
Evet. Çok fazla Savepoint (kayıt noktası) oluşturmak, PostgreSQL'in arka planda tutması gereken durum bilgisini artıracağı için performansı olumsuz etkileyebilir. Sadece kritik hata dönme ihtimali olan bloklarda kullanılmalıdır.
Sonuç
PostgreSQL Transaction yönetimi, güvenli ve tutarlı (ACID) uygulamalar geliştirmenin en büyük anahtarıdır. Hata (Exception) fırlatıldığında ROLLBACK yapmak veya karmaşık akışlarda SAVEPOINT kullanmak, sizi ileride saatlerce sürecek veri düzeltme mesailerinden kurtaracaktır. Veritabanınızın kalbi olan bu yapıları tüm Spring Boot veya Node.js projelerinizde (@Transactional) bilinçli bir şekilde kullanmayı unutmayın.