@Transactional anotasyonu hangi durumlarda çalışmaz? Self-invocation, rollback kuralları ve propagation tuzaklarını açıklayın.

Cevap

Spring @Transactional'ı AOP proxy ile uygular: bean'i çağırdığınızda aslında proxy'yi çağırırsınız; proxy transaction'ı açar, gerçek metodu çağırır, sonra commit/rollback yapar. Tuzakların çoğu bu mekanizmadan gelir.

1. Self-invocation

@Service
public class UserService {
    public void register(User u) {
        save(u);            // this.save() -> proxy atlanır, transaction YOK
    }

    @Transactional
    public void save(User u) { ... }
}

Aynı sınıf içinden çağrı proxy'den geçmez. Çözüm: @Transactional'ı dış metoda koymak, metodu ayrı bir bean'e taşımak veya TransactionTemplate kullanmak.

2. Görünürlük

Proxy tabanlı yaklaşımda anotasyon public olmayan metotlarda yıllarca yok sayıldı. Spring 6.0+ class-based proxy'lerde protected ve package-private metotları da destekler, ama private metotlar hiçbir zaman çalışmaz.

3. Rollback kuralları

Varsayılan olarak yalnızca unchecked exception (RuntimeException, Error) rollback tetikler. Checked exception (IOException vb.) fırlatılırsa transaction commit edilir.

@Transactional(rollbackFor = Exception.class)

Exception'ı metot içinde yakalayıp yutarsanız da rollback olmaz.

4. Propagation

  • REQUIRED (varsayılan): mevcut transaction'a katılır. İç metot exception fırlatıp dışarıda yakalansa bile transaction "rollback-only" işaretlenir ve dış commit UnexpectedRollbackException verir.
  • REQUIRES_NEW: mevcut transaction'ı askıya alıp yenisini açar (ör. hata olsa bile audit log yazmak). Ayrı bir DB bağlantısı kullanır; aşırı kullanımı connection pool'u tüketebilir.

5. Diğer tuzaklar

  • @Transactional metot içinde başlatılan @Async veya yeni thread transaction'ı paylaşmaz (transaction ThreadLocal'a bağlıdır).
  • Transaction içinde uzak HTTP çağrısı yapmak bağlantıyı uzun süre tutar; dış çağrıları transaction dışına alın.
  • readOnly = true okuma metotlarında Hibernate dirty checking'i atlayarak performans kazandırır.
  1. Java 21 virtual thread'ler nedir? Platform thread'lerden farkı nedir ve hangi durumlarda dikkatli olmak gerekir?OrtaJava & SpringBackend
  2. ExecutorService ve CompletableFuture ile asenkron iş nasıl yapılır? Thread pool boyutunu nasıl belirlersiniz?OrtaJava & SpringBackend
  3. JPA/Hibernate'te lazy ve eager loading farkı nedir? LazyInitializationException neden oluşur ve nasıl çözülür?OrtaJava & SpringBackend
  4. Spring bean scope'ları nelerdir? Singleton bir bean'e prototype bean inject edilirse ne olur?KolayJava & SpringBackend
  5. Spring'de Dependency Injection nedir? Constructor injection neden field injection'a tercih edilir?KolayJava & SpringBackend
  6. Java'da Garbage Collection nasıl çalışır? G1 ve ZGC arasındaki farklar nelerdir, hangisini ne zaman seçersiniz?ZorJava & SpringBackend

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle