Idempotency Key ve Veri Tutarlılığı¶
Idempotency, bir işlemin birden fazla kez çağrıldığında aynı sonucu garanti etmesi anlamına gelir. Bu özellik, dağıtık sistemlerde veri tutarlılığını sağlamak ve yinelenen işlemleri önlemek için kritik bir stratejidir.
1. Idempotency Nedir?¶
- Amaç: Aynı işlem birden fazla kez tekrarlandığında sistemin durumu değiştirmeden aynı sonucu döndürmesi.
- Kullanım Alanları: API çağrıları, ödeme sistemleri, mesajlaşma.
Örneğin, bir ödeme işlemi yinelenen bir API çağrısı nedeniyle birden fazla kez işlenmemelidir.
2. Idempotency Key Kullanımı¶
Idempotency Key, bir isteği benzersiz şekilde tanımlayan bir anahtardır. Bu anahtar, istemciden gelen isteğin tekrar işlenmesini engeller.
❌ Yanlış Kullanım: Idempotency Key olmadan istek işleme
public async Task ProcessPaymentAsync(PaymentRequest request)
{
// Tekrar eden istekleri kontrol etmeden işleme
await SavePaymentToDatabaseAsync(request);
await ChargeCustomerAsync(request);
}
✅ İdeal Kullanım: Idempotency Key ile kontrol
public async Task ProcessPaymentAsync(PaymentRequest request)
{
if (await IsRequestAlreadyProcessedAsync(request.IdempotencyKey))
{
Console.WriteLine("Request already processed. Skipping.");
return;
}
await SavePaymentToDatabaseAsync(request);
await ChargeCustomerAsync(request);
await MarkRequestAsProcessedAsync(request.IdempotencyKey);
}
3. Idempotency Key ve Veritabanı Kullanımı¶
Idempotency Key genellikle bir veritabanında saklanır ve her isteğin benzersiz olduğunu garanti eder.
✅ Örnek: Veritabanı ile Idempotency Key kontrolü
public async Task<bool> IsRequestAlreadyProcessedAsync(string idempotencyKey)
{
return await _dbContext.IdempotencyKeys.AnyAsync(k => k.Key == idempotencyKey);
}
public async Task MarkRequestAsProcessedAsync(string idempotencyKey)
{
await _dbContext.IdempotencyKeys.AddAsync(new IdempotencyKey { Key = idempotencyKey });
await _dbContext.SaveChangesAsync();
}
4. Mesajlaşma Sistemlerinde Idempotency¶
Mesajlar birden fazla kez işlenebilir, bu yüzden idempotent bir tasarım kullanmak önemlidir.
✅ Örnek: Mesaj işleme
public async Task ProcessMessageAsync(Message message)
{
if (await IsMessageAlreadyProcessedAsync(message.Id))
{
Console.WriteLine("Message already processed.");
return;
}
await HandleMessageAsync(message);
await MarkMessageAsProcessedAsync(message.Id);
}
5. Idempotency ve API Tasarımı¶
REST API’lerde idempotency, istemcilerin güvenilir bir şekilde veri gönderip almasını sağlar.
✅ Örnek: Idempotency Key ile API Çağrısı
POST /payments HTTP/1.1
Content-Type: application/json
Idempotency-Key: 12345
{
"amount": 100,
"currency": "USD"
}
Sunucu tarafında:
if (await IsRequestAlreadyProcessedAsync(request.Headers["Idempotency-Key"]))
{
return Ok("Request already processed.");
}
6. Loglama ve İzleme¶
Idempotency sistemlerinin düzgün çalıştığından emin olmak için loglama ve izleme araçları kullanın.
✅ Örnek: Loglama ile idempotency izleme
public async Task ProcessPaymentAsync(PaymentRequest request)
{
if (await IsRequestAlreadyProcessedAsync(request.IdempotencyKey))
{
Console.WriteLine($"Duplicate request detected: {request.IdempotencyKey}");
return;
}
await SavePaymentToDatabaseAsync(request);
Console.WriteLine($"Processed request: {request.IdempotencyKey}");
await MarkRequestAsProcessedAsync(request.IdempotencyKey);
}