Transactional outbox pattern nedir? Hangi problemi çözer ve nasıl uygulanır?

Cevap

Dual write problemi: bir servis hem veritabanına yazıp hem de bir mesaj kuyruğuna (Kafka, RabbitMQ) olay yayınlamak zorundaysa, bu iki işlem atomik değildir.

1. DB'ye siparişi kaydet       -> başarılı
2. Kafka'ya OrderCreated yayınla -> process çöktü / broker erişilemez
=> Sipariş var, ama hiçbir servis haberdar değil.

Sırayı tersine çevirmek de çözmez: olay yayınlanır ama DB transaction'ı rollback olursa, var olmayan bir siparişin olayı dolaşır.

Çözüm: outbox tablosu

Olay, iş verisiyle aynı veritabanında, aynı transaction içinde bir outbox tablosuna yazılır. Ayrı bir süreç (relay) bu tabloyu okuyup broker'a iletir.

BEGIN;
INSERT INTO orders (id, customer_id, total, status)
VALUES ('o-42', 'c-7', 150.00, 'PENDING');

INSERT INTO outbox (id, aggregate_type, aggregate_id, event_type, payload, created_at)
VALUES (gen_random_uuid(), 'order', 'o-42', 'OrderCreated',
        '{"orderId":"o-42","total":150.00}', now());
COMMIT;

Relay iki şekilde yapılır

  1. Polling publisher: bir job yayınlanmamış satırları periyodik olarak okur, broker'a gönderir, published_at işaretler. Birden fazla instance varsa SELECT ... FOR UPDATE SKIP LOCKED ile çakışma önlenir.
  2. Change Data Capture (CDC): Debezium gibi bir araç DB'nin transaction log'unu (PostgreSQL WAL, MySQL binlog) okuyup outbox insert'lerini Kafka'ya aktarır. Polling yükü yoktur, gecikme düşüktür.

Bilmeniz gerekenler

  • Garanti at-least-once'dır: relay mesajı gönderip published_at yazamadan çökerse mesaj tekrar gönderilir. Consumer'lar idempotent olmalı (olay ID'si ile dedup). Karşı tarafta bu yapıya inbox pattern denir.
  • Sıralama gerekiyorsa aggregate ID'yi Kafka message key olarak kullanın.
  • Outbox tablosu büyür; yayınlananları periyodik temizleyin veya partition'layın.
  • Saga'lar ve event-driven mimarilerde olay yayınlamanın standart güvenilir yoludur.
  1. Mesaj kuyruğu (RabbitMQ, Kafka) ne zaman kullanılır?ZorSistem TasarımıBackend
  2. Monolith ile mikroservis mimarisi arasındaki fark nedir? Mikroservislere ne zaman geçilmeli?ZorSistem TasarımıBackend
  3. CAP teoremi nedir? Gerçek sistemlerde nasıl yorumlanır?ZorSistem TasarımıBackend
  4. Dikey ve yatay ölçekleme arasındaki fark nedir?KolaySistem TasarımıFull Stack
  5. Hangi cache stratejilerini biliyorsunuz?OrtaSistem TasarımıFull Stack
  6. REST ile GraphQL arasındaki farklar nelerdir?OrtaSistem TasarımıFull Stack

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