2, Mar 2025
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:

  1. OrderService → Sipariş Oluştur
  2. PaymentService → Ödeme Al
  3. StockService → Stok Azalt
  4. NotificationService → Müşteriye Bildirim Gönder

💪 Neden Saga Pattern Kullanılır?

ProblemÇözüm
Dağıtık TransactionServisler arasında tutarlı işlem yönetimi
Retry ve TimeoutOtomatik yeniden deneme mekanizması
Veri TutarlılığıHata durumunda önceki adımları geri alma
Asenkron İşlemServisler arasında bağımsız işlem yürütme

🔄 Saga Pattern Türleri

Saga Pattern iki farklı yöntemle uygulanır:

TürAçıklamaKullanım Alanı
Orchestration-Based SagaMerkezi bir Coordinator tüm adımları yönetirBankacılık, Finans
Choreography-Based SagaServisler birbirleriyle doğrudan iletişim kurarE-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ış:

  1. Sipariş oluşturuldu
  2. Ödeme alındı
  3. Stok düşürüldü
  4. 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ışı:

  1. OrderService → OrderCreatedEvent gönderir
  2. PaymentService → OrderCreatedEvent‘i dinler ve ödeme alır
  3. StockService → PaymentSuccessEvent‘i dinler ve stok düşer
  4. 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öntemAvantajlarDezavantajlar
Orchestration-BasedMerkezi kontrol, Kolay hata yönetimiTek nokta bağımlılığı
Choreography-BasedGevşek bağımlılık, Yüksek ölçeklenebilirlikKarmaşık hata yönetimi

🔥 Hangi Yöntemi Seçmeliyim?

İhtiyaçYöntem
Transaction YönetimiOrchestration-Based
Event-Driven MimariChoreography-Based
Karmaşık AkışlarOrchestration-Based
PerformansChoreography-Based

Azure Service Bus + Saga Örneği

Azure üzerinde Service Bus kullanarak Orchestration tabanlı bir Saga kurabiliriz.


📌 Özet

ÖzellikAçıklama
Dağıtık Transaction
Compensation
Asenkron İşlem
Retry & Timeout

Bonus 🔥

Senin filesharingsecure projesinde şu akışı kullanabiliriz:

  1. Kullanıcı Dosya Yükler
  2. StorageService → Azure’a dosya yükler
  3. DatabaseService → Dosya bilgilerini DB’ye yazar
  4. 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

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir