Transaction ve ACID
| Özellik | Açıklama |
| Atomicity | Ya hep ya hiç - tüm işlemler başarılı veya hiçbiri |
| Consistency | Veri tutarlılığı korunur |
| Isolation | Eşzamanlı işlemler birbirini etkilemez |
| Durability | Commit edilen veri kalıcıdır |
Temel Transaction
BEGIN; -- veya START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- Hata yoksa kaydet
COMMIT;
-- veya hata varsa geri al
ROLLBACK;
Para Transferi Örneği
BEGIN;
-- Gönderenin bakiyesini kontrol et
DO $$
DECLARE
sender_balance NUMERIC;
BEGIN
SELECT balance INTO sender_balance FROM accounts WHERE id = 1;
IF sender_balance < 100 THEN
RAISE EXCEPTION 'Yetersiz bakiye';
END IF;
END $$;
-- Transfer işlemi
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- Log kaydı
INSERT INTO transfer_log (from_id, to_id, amount) VALUES (1, 2, 100);
COMMIT;
SAVEPOINT - Kısmi Geri Alma
BEGIN;
INSERT INTO orders (user_id, total_amount) VALUES (1, 500);
SAVEPOINT order_created;
INSERT INTO order_items (order_id, product_id, quantity) VALUES (1, 10, 2);
-- Hata oluşursa sadece item'ı geri al
ROLLBACK TO order_created;
-- Order hala mevcut, yeni denemeler yapılabilir
INSERT INTO order_items (order_id, product_id, quantity) VALUES (1, 20, 1);
COMMIT;
Isolation Levels
-- Transaction isolation level ayarla
BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
| Level | Dirty Read | Non-Repeatable | Phantom |
| Read Uncommitted | ❌ PostgreSQL'de yok | - | - |
| Read Committed | ✅ Engeller | ⚠️ Olabilir | ⚠️ Olabilir |
| Repeatable Read | ✅ Engeller | ✅ Engeller | ⚠️ Olabilir |
| Serializable | ✅ Engeller | ✅ Engeller | ✅ Engeller |
Deadlock Önleme
-- Her zaman aynı sırada kilitle
BEGIN;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
SELECT * FROM accounts WHERE id = 2 FOR UPDATE;
-- İşlemler...
COMMIT;
-- Timeout ayarla
SET lock_timeout = '10s';
SET statement_timeout = '30s';
Autocommit
-- PostgreSQL varsayılan autocommit açıktır
-- Her sorgu kendi transaction'ında çalışır
-- Autocommit kapatmak için (psql)
\set AUTOCOMMIT off