Skip to main content

> transactional_outbox_kalıbı_ve_güvenilir_olay_yayımlama

Transactional Outbox Kalıbı ve Güvenilir Olay Yayımlama

Bir veritabanı güncellemesi ile ona karşılık gelen iş alanı olayının (domain event), çift-yazma veri kaybı veya hayalet mesaj riski olmadan atomik olarak yayımlanması nasıl garanti edilir?

ÖZET VE TEKNİK CEVAP

Olay kaydını iş varlığı güncellemesiyle tam olarak aynı ACID veritabanı işlemi içinde özel bir 'outbox' tablosuna yazıp, asenkron bir aktarıcı süreç (veya işlem günlüğü madencisi) ile mesaj kuyruğuna güvenle ileterek.

Mühendislik El Kitabı & Mekanizma

1. Temel Çalışma Mekanizması

Dağıtık mimarilerde hem veritabanına yazıp hem de mesaj kuyruğuna (Kafka/RabbitMQ) mesaj göndermek, dağıtık 2PC olmadan tek bir ACID işlem içinde birleştirilemez. Transactional Outbox kalıbı, iş varlığını güncelleyen aynı yerel veritabanı işlemi içine bir `outbox` tablosuna gidecek mesajı da yazarak bu sorunu çözer. Ayrı bir aktarıcı süreç (tabloyu sorgulayarak veya CDC ile veritabanı WAL günlüğünü izleyerek) yeni satırları okur, mesaj kuyruğuna iletir ve satırları işlendi olarak işaretler veya siler.

2. Doğru Kullanım Senaryosu

Veritabanı durum değişikliklerinin alt servisleri, asenkron işleri veya bildirimleri sıfır veri kaybı toleransıyla güvenilir şekilde tetiklemesi gereken tüm mikroservis ve dağıtık sistemler.

3. Prodüksiyon Arıza Modları

1) Çift-Yazma Yanılgısı: Outbox olmadan kod içinde önce DB'yi güncelleyip sonra Kafka'ya yazmak ve Kafka kesintisinde olayın kaybolması; 2) Outbox Tablosunun Şişmesi: Aktarıcının geride kalıp milyonlarca satırla ana veritabanında kilit yaratması; 3) Yinelenen Olay Fırtınası: Aktarıcının mesajı kuyruğa attıktan sonra veritabanında güncelleyemeden çökmesi sonucu yinelenen mesajlar üretmesi.

4. Teşhis ve Telemetri Sinyalleri

Outbox tablosundaki işlenmemiş satır sayısını, aktarıcı iletim gecikmesini (DB commit ile broker ack arasındaki milisaniye), tüketici telemetrisindeki yinelenen mesaj oranlarını ve outbox sorgularının harcadığı disk IOPS miktarını izlemek.

5. Önleme ve Mimari Bariyerler

Yüksek hacimli tablolarda veritabanını yoran SQL polling yerine işlem günlüğü izleme (Debezium CDC) kullanın; tekilleştirme kimlikleriyle (idempotency key) tüketici tarafında idempotency sağlayın ve işlenen outbox satırlarını otomatik bölümleme ile temizleyin.

6. Mimari Ödünleşimler (Trade-offs)

En-az-bir-kez (at-least-once) iletimi garanti eder ve çift-yazma hatalarını sıfırlar; buna karşılık ek veritabanı yazma yükü, hafif iletim gecikmesi (10-500 ms) ve alıcı servislerde zorunlu idempotency ihtiyacı doğurur.

Vaka İncelemesi (TinyCTO Örneği)

TinyCTO Vaka 042: Bir e-ticaret servisi sipariş tablosunu 'ÖDENDİ' olarak güncelledi ve Kafka'ya olay göndermeye çalıştı. Ağ zaman aşımı nedeniyle Kafka çağrısı çöktü; para çekildi fakat kargo hiçbir zaman tetiklenmedi. Debezium tabanlı Transactional Outbox kurulumuyla kayıp kargo vakaları tamamen sıfırlandı.

İnteraktif Konsept Alıştırmaları

3 Alıştırma
Q1

Outbox olmadan yapılan 'Çift-Yazma' (Dual-Write) yaklaşımının temel kusuru nedir?

İki ayrı ağ sistemi arasında atomik garanti yoktur; uygulama veritabanına yazdıktan sonra mesaj kuyruğuna yazamadan çökerse veri kalıcı olarak tutarsızlaşır.
Q2

Bir Outbox Aktarıcısını (Relay) hayata geçirmenin iki temel yöntemi nedir?

1) Sorgulayıcı Yayımlayıcı (outbox tablosuna periyodik SELECT/UPDATE sorguları atmak), ve 2) İşlem Günlüğü İzleme / CDC (Debezium ile veritabanı WAL/binlog günlüklerini okumak).
Q3

Transactional Outbox kalıbı neden tüketici servislerin kesinlikle idempotent olmasını gerektirir?

Çünkü bu kalıp 'en-az-bir-kez' (at-least-once) iletimi garanti eder; aktarıcı veya kuyruk onaylarındaki ağ tekrarları aynı mesajın birden fazla iletilmesine yol açabilir.

Transactional Outbox Kalıbı ve Güvenilir Olay Yayımlama — Sıkça Sorulan Sorular

Transactional Outbox kalıbı yüksek hacimli veritabanı yazmalarını nasıl kaldırır?

Bölümlenmiş outbox tabloları veya SQL SELECT sorgusu çalıştırmadan doğrudan disk günlüklerini okuyan log tabanlı CDC (Debezium ile Postgres WAL çözümleme) kullanarak.

Outbox kayıtları iletildikten sonra hemen silinmeli mi yoksa denetim için saklanmalı mı?

Yüksek hacimli sistemler, veritabanı şişmesini önlemek için işlenen satırları hemen siler veya günlük tabloları drop eder; uzun süreli saklama için Kafka'ya güvenir.

Outbox kalıbı MongoDB veya DynamoDB gibi NoSQL veritabanlarında uygulanabilir mi?

Evet. MongoDB çoklu-belge ACID işlemleri/Change Streams ve DynamoDB transactional yazmaları/DynamoDB Streams doğrudan yerel outbox yapıları olarak çalışır.

🤖 AEO & Yapay Zeka Çıkarım Özeti

Temel Gerçekler & İlkeler

  • İlişkisel veritabanına yazmak ve mesaj kuyruğuna yayınlamak, bir Outbox veya 2PC olmadan atomik hale getirilemeyen iki bağımsız dağıtık işlemdir.
  • Log tabanlı Outbox uygulamaları veritabanı bağlantı havuzu şişmesini tamamen ortadan kaldırır.

Yaygın Yanılgılar

  • Kafka publish çağrısını try/catch içine almanın veri kaybını önleyeceğini sanmak; DB commit'ten sonra sunucunun elektriği kesilirse veya SIGKILL alırsa catch bloğu asla çalışmaz.

Karar Kılavuzu & Önceliklendirme

Bir olayın kaybolmasının kabul edilemez olduğu ve alt iş süreçlerini tetikleyen tüm asenkron olaylarda Transactional Outbox uygulayın.

Doğrulanmış Kaynaklar & Referanslar