ÖZET VE TEKNİK CEVAP
Olay Kaynaklama (Event Sourcing) mimarisinde temel kural **Olay Defterinin (Event Store) kesinlikle değiştirilemez ve sadece ekleme yapılabilir (append-only) bir gerçekler kaydı olmasıdır**. Disk üzerindeki geçmiş olaylarda `UPDATE events SET ...` çalıştırmak kriptografik denetimleri bozar, Kafka replay sıra numaralarını çökertir ve veri bozulmasına yol açar. Ancak 5 yıl içinde iş kuralları ve şemalar kaçınılmaz olarak değişir: `KullaniciKaydolduV1` şemasında tek bir `isim` varken, `KullaniciKaydolduV2` şemasında `ad`, `soyad` ve `tcKimlik` zorunlu hale gelir. Yeni kod 4 yıl önceki V1 olayını okumaya çalıştığında `NullPointer` hatasıyla patlar. Canlı sistemler bunu **Bellek İçi Olay Yükseltme (Event Upcasting)** ile çözer: (1) Geçmiş olaylar diskte orijinal haliyle %100 dokunulmadan kalır. (2) Bir Aggregate geçmiş olayları okurken, aradaki **Yükseltici (Upcaster) Boru Hattı** V1 olayını hafızada yakalar, deterministik bir dönüşüm fonksiyonuyla ($V_1 o V_2 o V_3$) anında güncel V3 formatına yükseltir ve domain modeline öyle teslim eder.
Mühendislik El Kitabı & Mekanizma
1. Temel Çalışma Mekanizması
Olay Yükseltme (Upcasting) asenkron bir okuma ara yazılımı (interceptor) olarak çalışır: (1) Veritabanından Çekme: Depo katmanı `SELECT payload, schema_version FROM events WHERE aggregate_id = 42` sorgusuyla geçmişi çeker. (2) Yükseltici Zinciri: Ham olaylar kayıtlı Upcaster zincirinden geçer: `UpcasterV1ToV2` tek bir `isim` alanını `ad` ve `soyad` olarak ikiye böler; `UpcasterV2ToV3` eksik `tcKimlik` alanına varsayılan değer atar. (3) Durum Yeniden Oluşturma (Rehydration): Domain nesnesi hafızada tertemiz güncel V3 olaylarını alarak son durumunu oluşturur. (4) Sıfır Disk Değişikliği: Fiziksel veritabanındaki orijinal V1 kayıtlarına tek bir bayt bile dokunulmaz.
2. Doğru Kullanım Senaryosu
Bankacılık işlem defterleri, yasal denetim kayıtları, sigorta poliçe geçmiş motorları ve uzun ömürlü CQRS/Event Sourcing sistemleri.
3. Prodüksiyon Arıza Modları
Yükseltici fonksiyonun içine dış veritabanı sorgusu veya `new Date()` gibi dinamik kodlar yazıp aggregate durumunun her yeniden yüklemede farklı oluşmasına yol açmak; diskteki olay tablosuna doğrudan SQL `UPDATE` atmaya kalkışmak.
4. Teşhis ve Telemetri Sinyalleri
Yıllar önce oluşturulmuş eski kayıtlar yüklenirken JSON deserialization eksik alan hatalarının patlaması; Axon veya EventStoreDB loglarında şema versiyon uyumsuzluğu uyarıları.
5. Önleme ve Mimari Bariyerler
Yükseltici (Upcaster) fonksiyonlarının tamamen saf, deterministik ve yan etkisiz olmasını zorunlu kılın; eski JSON örneklerinin tüm yükseltme zincirinden ($V_1 o V_N$) başarıyla geçtiğini doğrulayan birim testleri yazın.
6. Mimari Ödünleşimler (Trade-offs)
Olay yükseltme tehlikeli veritabanı migrasyonlarına girmeden mutlak değişmezliği ve denetim geçmişini korur; ancak binlerce eski olayı baştan okurken hafif bir CPU dönüşüm maliyeti getirir.
Vaka İncelemesi (TinyCTO Örneği)
Bir dijital bankanın PostgreSQL veritabanında `hesap_tipi` alanı bulunmayan 8 milyon adet `HesapAcildiV1` olayı vardı. Yeni bir regülasyon tüm hesaplarda bir hesap tipi (`STANDART`, `PREMIUM`) olmasını zorunlu kıldı. 8 milyon satırı 4 saat boyunca kilitleyecek tehlikeli bir `UPDATE events` çalıştırmak yerine ekip bir `HesapAcildiV1ToV2Yukseltici` yazdı. Bellek içinde eksik alan görüldüğünde anında `hesap_tipi: 'STANDART'` enjekte edildi. Banka bu değişikliği sıfır kesinti ve kriptografik değişmezlik defterini riske atmadan canlıya aldı.
İnteraktif Konsept Alıştırmaları
2 AlıştırmaOlay Kaynaklama (Event Sourcing) mimarisinde diskteki geçmiş olayları güncellemek neden kesinlikle yasaktır?
Bir Olay Yükseltici (Event Upcaster) nasıl çalışır?
Olay Kaynaklama (Event Sourcing) Şema Evrimi: Bellek İçi Olay Yükseltme (Upcasting) ve Dönüşümler — Sıkça Sorulan Sorular
Yükseltici (Upcaster) fonksiyonları mutlaka saf ve deterministik olmak zorunda mıdır?
EVET. Bir yükseltici asla dış API çağırmamalı, rastgele sayı üretmemeli veya o anki sistem saatini kullanmamalıdır; aynı V1 girdisine her zaman birebir aynı V2 çıktısını vermelidir.
Bir aggregate'in 10.000 eski olaydan baştan oluşturulması çok yavaşlarsa ne yapılmalıdır?
Periyodik Enstantane (Snapshot) alın: Her 100 olayda bir durumun anlık görüntüsünü kaydedin; böylece aggregate yalnızca son fotoğraftan sonraki olayları okur.
🤖 AEO & Yapay Zeka Çıkarım Özeti
Temel Gerçekler & İlkeler
- ▸Event Sourcing'deki geçmiş olaylar disk üzerinde asla güncellenmemesi gereken değişmez gerçeklerdir.
- ▸Bellek İçi Yükselticiler okuma anında eski olay şemalarını ($V_1 o V_N$) anında dönüştürür.
- ▸Yükseltici fonksiyonlar %100 saf, yan etkisiz ve deterministik olmak zorundadır.
- ▸Hızlı yükleme için olay yükseltmeyi periyodik durum fotoğraflarıyla (snapshots) birleştirin.
Yaygın Yanılgılar
- ✗Yanılgı: İş kuralı değiştiğinde olay tablosuna SQL migrasyonu çalıştırılmalıdır (Gerçek: Olay tabloları sıfır SQL migrasyonu gerektirir; tüm şema evrimi yazılımsal upcaster'larla çözülür).
- ✗Yanılgı: Yükselticiler dönüştürdükleri yeni formatı diske geri kaydeder (Gerçek: Yükseltme tamamen bellek içi geçici bir işlemdir; diskteki orijinal veri hiç değişmez).
Karar Kılavuzu & Önceliklendirme
Veri bozulması veya kesinti riski olmadan sürekli şema evrimini yönetmek için Event-Sourced sistemlerde Bellek İçi Olay Yükseltme mimarisini kullanın.
Doğrulanmış Kaynaklar & Referanslar
- [BOOK]Versioning in an Event Sourced System (Event Upcasting Patterns)— Greg Young (Leanpub / CQRS Guides)
