Saga Pattern Nedir?
Saga Pattern, dağıtık mikroservis mimarilerinde veri tutarlılığı (data consistency) ve işlem bütünlüğü (transaction integrity) sağlamak için kullanılan bir transaction orchestration desenidir.
Monolitik yapılarda ACID (Atomicity, Consistency, Isolation, Durability) özellikleri ile veritabanı işlemleri tek bir transaction olarak gerçekleştirilir. Ancak, mikroservis mimarisinde her servis kendi veritabanını yönettiği için dağıtık transaction yönetimi zorlaşır.
İşte burada Saga Pattern devreye girer.
🔑 Saga Pattern Nasıl Çalışır?
Saga Pattern, bir işlemi bir dizi küçük, bağımsız transaction’lara böler. Her bir işlem başarılı olduğunda bir sonraki adıma geçilir. Eğer bir adımda hata oluşursa Compensation (Telafi İşlemi) mekanizması devreye girer ve önceki başarılı adımlar geri alınır.
🔥 Örnek Senaryo
Bir e-ticaret uygulamasında Sipariş Süreci:
- OrderService → Sipariş Oluştur
- PaymentService → Ödeme Al
- StockService → Stok Azalt
- NotificationService → Müşteriye Bildirim Gönder
💪 Neden Saga Pattern Kullanılır?
Problem | Çözüm |
---|---|
Dağıtık Transaction | Servisler arasında tutarlı işlem yönetimi |
Retry ve Timeout | Otomatik yeniden deneme mekanizması |
Veri Tutarlılığı | Hata durumunda önceki adımları geri alma |
Asenkron İşlem | Servisler arasında bağımsız işlem yürütme |
🔄 Saga Pattern Türleri
Saga Pattern iki farklı yöntemle uygulanır:
Tür | Açıklama | Kullanım Alanı |
---|---|---|
Orchestration-Based Saga | Merkezi bir Coordinator tüm adımları yönetir | Bankacılık, Finans |
Choreography-Based Saga | Servisler birbirleriyle doğrudan iletişim kurar | E-Ticaret, Event-Driven Mimari |
🔑 1. Orchestration-Based Saga
Bu yöntemde, bir Saga Coordinator tüm işlemleri yönetir.
Örnek Mimari:
lessCopyEdit[OrderService] ---> [Saga Coordinator] ---> [PaymentService]
|
---> [StockService]
|
---> [NotificationService]
Örnek Akış:
- Sipariş oluşturuldu
- Ödeme alındı
- Stok düşürüldü
- Bildirim gönderildi
Eğer StokService başarısız olursa:
- Ödeme geri alınır
- Sipariş iptal edilir
🛠️ Kod Örneği (C# + .NET Core)
İlk olarak, MassTransit kütüphanesini kullanarak bir Saga Coordinator yazalım.
Paket Yükleme
bashCopyEditInstall-Package MassTransit
Install-Package MassTransit.EntityFrameworkCore
Saga Tanımı
csharpCopyEditpublic class OrderState : SagaStateMachineInstance
{
public Guid CorrelationId { get; set; }
public string CurrentState { get; set; }
}
Saga State Machine
csharpCopyEditpublic class OrderStateMachine : MassTransitStateMachine<OrderState>
{
public OrderStateMachine()
{
InstanceState(x => x.CurrentState);
Event(() => OrderSubmitted, x => x.CorrelateById(context => context.Message.OrderId));
Initially(
When(OrderSubmitted)
.Then(context =>
{
Console.WriteLine($"Order Received: {context.Data.OrderId}");
})
.TransitionTo(Submitted));
}
public Event<OrderSubmitted> OrderSubmitted { get; set; }
public State Submitted { get; private set; }
}
Compensation (Telafi İşlemi)
csharpCopyEditpublic class PaymentService
{
public async Task<bool> ProcessPayment(Guid orderId)
{
Console.WriteLine($"Payment processed for Order {orderId}");
// Eğer başarısız olursa Exception fırlat
return true;
}
public async Task<bool> RollbackPayment(Guid orderId)
{
Console.WriteLine($"Payment Rolled Back for Order {orderId}");
return true;
}
}
🔑 2. Choreography-Based Saga
Bu yöntemde herhangi bir merkezi koordinatör yoktur. Servisler Event-Driven yapıda birbirleriyle haberleşir.
Örnek Event Akışı:
- OrderService → OrderCreatedEvent gönderir
- PaymentService → OrderCreatedEvent‘i dinler ve ödeme alır
- StockService → PaymentSuccessEvent‘i dinler ve stok düşer
- NotificationService → StockUpdatedEvent‘i dinler ve e-posta gönderir
Event Bus Yapısı (RabbitMQ ile)
csharpCopyEditpublic interface IOrderCreated
{
Guid OrderId { get; }
}
public class OrderCreated : IOrderCreated
{
public Guid OrderId { get; set; }
}
Avantajlar ve Dezavantajlar
Yöntem | Avantajlar | Dezavantajlar |
---|---|---|
Orchestration-Based | Merkezi kontrol, Kolay hata yönetimi | Tek nokta bağımlılığı |
Choreography-Based | Gevşek bağımlılık, Yüksek ölçeklenebilirlik | Karmaşık hata yönetimi |
🔥 Hangi Yöntemi Seçmeliyim?
İhtiyaç | Yöntem |
---|---|
Transaction Yönetimi | Orchestration-Based |
Event-Driven Mimari | Choreography-Based |
Karmaşık Akışlar | Orchestration-Based |
Performans | Choreography-Based |
Azure Service Bus + Saga Örneği
Azure üzerinde Service Bus kullanarak Orchestration tabanlı bir Saga kurabiliriz.
📌 Özet
Özellik | Açıklama |
---|---|
Dağıtık Transaction | ✔ |
Compensation | ✔ |
Asenkron İşlem | ✔ |
Retry & Timeout | ✔ |
Bonus 🔥
Senin filesharingsecure projesinde şu akışı kullanabiliriz:
- Kullanıcı Dosya Yükler
- StorageService → Azure’a dosya yükler
- DatabaseService → Dosya bilgilerini DB’ye yazar
- NotificationService → Kullanıcıya bildirim gönderir
💪 Best Practice
- Outbox Pattern ile birlikte kullan
- Idempotent işlemler kullan (Tekrar eden isteklerde veri bütünlüğünü korur)
- Merkezi bir Loglama Servisi ekle