Transaction, veritabanında atomiklik, tutarlılık, izolasyon ve kalicilik (ACID) garantilerini saglayan mantiksal is birimidir. Transaction sinirinin yanlış cizilmesi uzun kilitler, deadlock, connection pool tukenmesi ve kismi commit hatalarina yol acar. Modern uygulamalarda tek dev transaction yerine kisa transaction'lar, saga pattern ve outbox ile eventual consistency tercih edilir. Bu yazida isolation level, transaction scope tasarımı, distributed transaction sınırları ve pratik kalıplari inceliyoruz.
ACID ozeti
Atomicity: Ya hepsi ya hic. Consistency: Kisitlar korunur. Isolation: Eszamanli işlemler birbirini gorunmez şekilde etkiler. Durability: Commit kalicidir. Transaction sınırı bu garantilerin geçerli olduğu kod ve SQL kapsamini belirler.
Isolation level'lar
- Read Uncommitted: Dirty read mümkün; nadiren kullanılır.
- Read Committed: Varsayilan çoğu motorde; non-repeatable read mümkün.
- Repeatable Read: Ayni transaction'da tekrar okuma ayni sonucu verir.
- Serializable: En güçlü; phantom read onlenir; performans maliyeti yüksek.
Serializable gereksiz kullanım deadlock ve timeout üretir. Varsayilan seviye çoğu OLTP icin yeterlidir.
Transaction ne kadar kisa olmali
Transaction acikken network çağrısı, kullanıcı input bekleme, dosya I/O veya mesaj kuyrugu publish yapilmamali. Ideal transaction yalnizca veritabanı islemlerini kapsar. Uzun is mantigi transaction dışında parcalanir.
await using var tx = await db.Database.BeginTransactionAsync();
try {
await db.Orders.AddAsync(order);
await db.SaveChangesAsync();
await tx.CommitAsync();
} catch {
await tx.RollbackAsync();
throw;
}
// E-posta ve mesaj transaction SONRASI
Unit of Work pattern
EF Core DbContext bir request/scoped unit of work'tur. Tek SaveChanges bir transaction olabilir. Birden fazla SaveChanges ayni transaction'da birlestirilebilir. Repository her cagrida SaveChanges yapmamali; scope sonunda tek commit tercih edilir.
Deadlock
Iki transaction farklı sırada kaynak kilitleyince deadlock olusur. Çözüm: tutarlı lock sırası (parent sonra child), kisa transaction, uygun indeks (row lock yerine page lock riski). Retry logic deadlock victim icin uygulanabilir.
Distributed transaction (2PC)
Iki veritabanı veya DB + message broker arasinda 2PC (MSDTC) karmaşık ve yavas. Microservice mimarisinde avoided. Saga: her adim yerel transaction; telafi (compensating) transaction ile geri alma.
Saga ornegi
- Order oluştur (Committed)
- Stok rezerve et (Committed veya compensate: stok iade)
- Odeme al (Committed veya compensate: iade)
Her adim ayri transaction; orchestrator veya choreografi durumu yönetir.
Optimistic concurrency
RowVersion ile cakisma tespiti; transaction kisa tutulur. Retry veya kullanıcıya conflict mesaji. Pessimistic lock (SELECT FOR UPDATE) stok dusuklugunda dusunulur; sure kisa olmali.
Read-only transaction
Salt okuma islemleri ayri kisa transaction veya snapshot isolation ile çalışır. Rapor sorgulari yazma transaction'indan ayri connection kullanmali.
Connection pool etkilesimi
Uzun transaction connection'i tutar; pool tukenince istekler bekler. Timeout hatalari transaction suresi ile koreledir. Async/await transaction suresini uzatmamali; ConfigureAwait ve senkron bloklama dikkat.
Test
Integration testlerde transaction rollback ile izolasyon: test sonunda rollback, veri kalmaz. Production'da ayni pattern kullanılmaz.
Anti-pattern'ler
- HTTP istegi boyunca açık transaction
- Cross-service tek transaction beklentisi
- SaveChanges her satirda
Özet
Transaction kisa, odaklı ve yalnizca DB islemlerini kapsamali. Isolation level ihtiyaca gore secilmeli. Dagitik is akislari saga ve outbox ile yonetilmeli. Ölçüm: transaction suresi, deadlock sayisi, pool bekleme suresi.
Nested transaction ve savepoint
Çoğu veritabanı gerçek nested transaction desteklemez; SAVEPOINT ile simule edilir. EF Core veya ADO.NET'te açık transaction varken ikinci BeginTransaction savepoint oluşturur. Savepoint rollback yalnizca ic blok geri alir; dis transaction devam eder. Derin nested yapı anlasilmazlik ve deadlock riski tasir.
Outbox ve eventual consistency
Transaction icinde domain state ve outbox mesaji birlikte commit edilir. Ayri mesaj broker yazimi iki-phase commit gerektirir veya tutarsizlik riski dogurur. Outbox dispatcher arka planda mesajlari publish eder; at-least-once delivery icin consumer idempotent olmalidir.
Read-only transaction ve snapshot
PostgreSQL REPEATABLE READ veya SERIALIZABLE read-only transaction tutarlı rapor okur. Uzun rapor sorgulari kisa yazma transaction'indan ayri connection'da calistirilmalidir. SQL Server read committed snapshot isolation (RCSI) okuyucu-yazici bloklamasini azaltir.
Transaction anti-pattern ozeti
Uzun transaction, kullanıcı etkilesimi bekleyen transaction, HTTP çağrısı icinde açık transaction, gereksiz Serializable, transaction dışında cok adimli is mantigi ve saga yerine dev transaction kullanan tasarımlar production incident kaynagidir. Her use case icin minimum tutarlılık seviyesi ve minimum transaction suresi hedeflenmelidir.