Shared Database Anti-Pattern'ini Tanımak
İki servis, aynı foreign key

Diyagramda iki altıgen, ortada bir silindir. Silindir 'geçici' yazıyor. Geçici, altı aydır orada. Faturalandırma {orders.invoice_status} kolonunu güncelliyor, sipariş {orders.status} kolonunu güncelliyor, rapor ikisini join ediyor. Deploy günü bir {ALTER} iki host'u birlikte düşürüyor. Buna ayrı servis demiyorum.
Paylaşılan veritabanı bir günah listesi değil. Aynı process'te aynı veritabanı, monolith'in doğal hali. Anti-pattern, process'i ayırıp yazmayı ayırmamak. Ağ var, sahiplik yok.
Tanı
Bakınan şey bağlantı cümlesi. İki host aynı kullanıcıyla aynı şemaya giriyorsa, şüphe. İki host aynı tabloya {UPDATE} atıyorsa, teşhis. Biri okuyup biri yazıyorsa konuşulur: okuma modeli mi, sızıntı mı? İkisi de yazıyorsa konuşulacak az şey vardır — sınır yok.
-- sipariş host'u
UPDATE orders SET status = 'paid' WHERE id = $1;
-- fatura host'u, aynı tablo
UPDATE orders SET invoice_status = 'issued', invoice_id = $2
WHERE id = $1;
-- rapor host'u
SELECT o.status, o.invoice_status, i.pdf_url
FROM orders o
JOIN invoices i ON i.order_id = o.id;
Üçü de 'doğru' SQL. Üçü birden, {orders} 'u bir sözleşmeye çevirir. Kolon eklemek üç consumer. Kolon silmek üç kırılma. Veritabanı, yayınlanmamış bir API olur. API olduğu halde versiyonu yoktur.
Foreign key sınırın ötesinde
Servisler arası FK, cesur durur: referans bütünlüğü. Bedeli, karşı tablonun silinememesi, migrate sırasının kilitlenmesi, gece restore'unun iki ekibi ilgilendirmesi. Bütünlüğü uygulama veya outbox ile kurmak daha gevşek, daha bağımsız. Gevşekliği kaldıramıyorsanız, zaten ayrı servis değilsiniz.
Elif'in EXPLAIN yazısındaki gibi, planı okumadan 'join ucuz' demek de buraya sızıyor. İki servis aynı silindiri paylaşınca, birinin ağır raporu diğerinin yazmasını kilitler. Ayrı host, aynı kilit. Process sınırı, kilit sınırını kesmez.
Ne yapıyorum
İlk adım yeni veritabanı değil. Yazmayı tek yere almak. Fatura, siparişe kolon yazmasın; kendi satırını yazsın, sipariş bir olayla {Paid} görsün veya sipariş fatura kimliğini kendi transaction'ında saklasın — tek yazar. Rapor, kopya okusun.
CREATE TABLE billing.invoices (
id uuid PRIMARY KEY,
order_id uuid NOT NULL UNIQUE,
status text NOT NULL,
issued_at timestamptz NOT NULL
);
-- orders şemasına invoice_status kolonu yok
Aynı cluster, ayrı şema, tek yazar. Bu hâlâ tek veritabanı. Anti-pattern'i kırmaya yeter mi? Yazma için evet. Operasyon için hayır: yedek ve migrate hâlâ ortak. Ortak operasyon, ortak kader. Kaderi ayırmak ikinci adım, ihtiyaç olunca.
Paylaşılan veritabanını 'mikroservis yaptık' cümlesinden tanımıyorum. {information_schema} ve kim {UPDATE} atıyor, oradan tanıyorum. Host sayısı yalan söyleyebilir. Yazma yeri söylemez.
Yorumlar
Yorumlar (0)
Yorumlar üyelere açık. Üye ol · Giriş yap