Data ownership, bir modülün hangi veriyi ve hangi iş kurallarını yönettiğini açıkça belirlemektir. Modular Monolith içinde tek database kullanmak bu sahipliği ortadan kaldırmaz; başka bir modülün iç tablolarına gelişigüzel erişmek ise değişiklikleri birbirine bağlar.
Boundary yalnız kod klasörlerinde kurulmaz. Veri modelinin, yazma yetkisinin ve modüller arası sözleşmelerin de aynı sınırı desteklemesi gerekir.

Burada ortak database, schema ayrımı, okuma ihtiyacı ve transaction sınırlarını ele alıyorum. Amaç bütün modülleri fiziksel olarak ayırmak değil; hangi bağımlılığın bilinçli, hangisinin tesadüfen oluştuğunu görünür kılmak.
Data ownership ve shared database
“Aynı database ise istediğim tabloya erişebilirim” yaklaşımı, modülün uygulama sözleşmesi yerine iç veri modeline bağımlılık kurar. Order modülü Inventory tablosunu doğrudan güncellerse stok invariant’larını atlayabilir. Salt okuma da schema değişikliklerini iki modülün birlikte yönetmesini gerektirebilir.
Tercihim, her modülün kendi tablolarını ve migration’larını yönetmesi; diğer modüllere ihtiyacı kadar bir contract sunmasıdır. Aynı deployment içinde bu contract bir in-process application service olabilir. Sırf modülerlik için HTTP çağrısı veya message broker eklemek gerekmez.
Data ownership bir fiziksel server sayısı kuralı değildir. Microservices’te de private table, ayrı schema veya ayrı database seçenekleri vardır; veri erişimini sahibinin kontrol etmesi ve lifecycle sınırı belirleyicidir. Database per service pattern’i bu ayrımları gösteriyor.
Schema ve erişim kuralları
Schema destekleyen bir veritabanında order, inventory ve billing ayrımı sahipliği görünür kılar. Ancak naming veya schema tek başına erişimi engellemez. Modüllerin başka bir modülün DbContext, repository veya entity tiplerini kullanmasını sınırlayın; architecture testleri ve code review ile kuralı kontrol edin. Gerektiğinde database permission ve ayrı connection kimlikleriyle de sınır koyabilirsiniz.
Schema her provider’da aynı şekilde çalışmaz; örneğin SQLite bu ayrımı desteklemez. Ayrı database daha güçlü bir erişim/deployment sınırı kurabilir, fakat bu da credential ve permission yapılandırmasına bağlıdır. Buna karşılık backup, migration, bağlantı yönetimi ve transaction koordinasyonu ek maliyet getirir. EF Core’un table schema dokümantasyonu provider farklarını açıklıyor.
Cross-module foreign key ve ortak entity kullanımı da schema değişikliklerini bağlayabilir. Bunları otomatik olarak yasaklamak yerine gerekçeyi ve etkilenen sahipleri kaydedin. İleride modülü ayırmak hedefleniyorsa bu bağımlılıkların taşıma maliyetini özellikle değerlendirin.
Okuma ihtiyacı ve read contract
Bir modül diğerinin verisini okumak istediğinde ilk seçenek, sahibinin sunduğu application contract olmalı. Böylece çağıran taraf tablo ve kolon ayrıntılarına bağlanmaz. Bununla birlikte reporting veya yüksek hacimli okuma için sürekli senkron çağrı uygun olmayabilir.
Bu durumda sahibinin yayımladığı bir read contract, reporting view veya ayrı projection değerlendirin. Buradaki ayrım, private tabloya plansız erişim ile desteklenen bir okuma sözleşmesidir. View’ın schema değişikliklerini ve uyumluluğunu kimin yönettiğini belirleyin.
Asenkron projection seçerseniz gecikmeyi, yeniden oluşturmayı ve duplicate event davranışını tasarlayın. Cache eklemek tek başına ownership sorununu çözmez; cache’i private tablolardan besliyorsanız aynı coupling devam eder. Materialized View pattern’i read model’in tutarlılık ve bakım maliyetini ele alıyor. CQRS, bu ihtiyaç belirginleştiğinde yararlı olabilir; her modüle ayrı read model zorunlu değildir.
Data ownership ve transaction sınırı
Her modülün kendi yazma kurallarını yönetmesi iyi bir varsayılandır. Ancak “her modül mutlaka ayrı transaction kullanmalı” kuralı, aynı database’de atomik olması gereken bir iş akışını gereksiz yere eventual consistency’ye zorlayabilir.
Örneğin sipariş kaydı ve stok rezervasyonu tek commit gerektiriyorsa, sahip modüllerin contract’larını koruyan bir application coordinator ortak local transaction kullanabilir. EF Core’da aynı DbConnection ve DbTransaction paylaşımıyla cross-context transaction mümkündür. Bu, business invariant’a verilmiş bilinçli bir karar olmalı; başka modülün tablolarına doğrudan yazmakla aynı şey değildir. Ayrıntılar EF Core transaction dokümantasyonunda yer alıyor.
Ortak transaction modüllerin bağımlılığını artırır ve gelecekte ayrı deployment’a geçişi zorlaştırabilir. Buna karşılık ayrı transaction seçimi partial failure, retry ve gerekirse compensation gerektirir. Veri değişikliğiyle event kaydını birlikte tutmak gerekiyorsa transactional outbox kullanmayı değerlendirin; mesaj tesliminin tekrar edebileceğini ve consumer idempotency’sini ayrıca ele alın.
Mevcut coupling nasıl azaltılır?
Her modül her tabloya erişiyorsa düzeltme maliyeti yüksektir; fakat veri bağımlılıkları kalıcı veya sistem kurtarılamaz değildir. Önce hangi modülün hangi tabloyu okuduğunu ve yazdığını çıkarın. Ardından tek bir iş akışında sahipliği belirleyip doğrudan erişimi contract arkasına alın. Migration, backfill ve davranış kontrolleriyle adım adım ilerleyin.
Microservices’e geçmek bu bağımlılıkları kendiliğinden çözmez. Önce mantıksal sınırların çalıştığını görmek, fiziksel ayrımın maliyetini değerlendirmeyi kolaylaştırır. Sınırları belirlerken Domain Boundary ve DDD ilişkisini; ayrı deployment ihtiyacı oluştuğunda Microservices’e geçiş sinyallerini birlikte inceleyebilirsiniz.
