---
title: "Idempotency ve Duplicate Booking Prevention"
description: "Travel booking create, payment, cancellation ve refund operasyonlarında idempotency sınırlarını ve duplicate booking önleme desenlerini tasarlayın."
slug: "idempotency-duplicate-booking-prevention"
translationKey: "architecture-idempotency-duplicate-booking-prevention"
locale: "tr"
type: "guide"
category: "architecture"
tags: ["idempotency","duplicate-booking","retry","booking","travel"]
publishedAt: "2026-09-27"
updatedAt: "2026-09-27"
reviewedAt: "2026-09-27"
technicalVerifiedAt: "2026-09-27"
codeExampleStatus: "illustrative"
---

Travel booking'de retry güvenli değildir; **aynı business intent'in ikinci kez uygulanmasını engelleyen idempotency sınırı** olmadan network recovery duplicate booking veya double charge üretebilir.

## Idempotency nerede uygulanmalı?

Ayrı operation'lar ayrı key ister:

- booking create,
- payment authorize,
- payment capture,
- booking modify,
- booking cancel,
- refund.

Bir operation key'ini başka semantic operation için reuse etmeyin.

## Canonical key

```text
bookingIntentId + operation + version
```

Örnek:

```text
book:bi_123:v1
capture:bi_123:v1
cancel:bk_987:v1
refund:pay_456:v1
```

Key deterministic olmalı ama PII taşımamalıdır.

## Internal idempotency store

```json
{
  "key": "book:bi_123:v1",
  "operation": "BOOK",
  "status": "IN_PROGRESS",
  "requestHash": "sha256:...",
  "resultReference": null,
  "expiresAt": "2026-09-28T10:00:00Z"
}
```

Aynı key farklı request payload ile gelirse conflict olarak ele alınmalıdır.

## Duplicate prevention flow

```mermaid
%% title: Duplicate booking prevention
%% description: Booking create önce idempotency store ile kontrol edilir; mevcut attempt varsa yeni provider create başlatılmaz.
flowchart LR
  A[Create Booking Request] --> B[Idempotency Lookup]
  B -->|new| C[Reserve Key]
  B -->|existing| D[Return Existing State]
  C --> E[Provider Create]
  E --> F[Persist Result]
  F --> G[Return Booking State]
```

## Provider idempotency varsa

Provider native idempotency key destekliyorsa internal key ile provider key arasında mapping saklayın. Bu internal dedup ihtiyacını ortadan kaldırmaz; client retry ve provider retry ayrı katmanlardır.

## Provider idempotency yoksa

Daha sıkı guard gerekir:

- aynı BookingIntent için tek active create attempt,
- distributed lock veya unique constraint,
- UNKNOWN state'te create retry yok,
- provider lookup zorunlu,
- manual override audit trail.

## Database guard

Useful constraint örneği:

```text
UNIQUE (booking_intent_id, operation, operation_version)
```

Distributed lock tek başına yeterli değildir; lock expire olabilir. Kalıcı uniqueness daha güçlü son savunmadır.

## Request hash

Aynı key ile farklı semantic request gelmesini önleyin. Hash'e yalnız stable booking fields koyun:

- selected offer version,
- traveler/passenger canonical identity reference,
- dates/segments,
- amount/currency,
- operation.

Raw JSON field order'a bağlı hash üretmeyin.

## Retry semantics

Aynı idempotency key ile retry:
- IN_PROGRESS → mevcut state dön,
- CONFIRMED → aynı sonucu dön,
- FAILED → explicit policy'ye göre yeni operation version gerekebilir,
- UNKNOWN → yeni provider create başlatma; reconciliation'a yönlendir.

## Failure modes

- idempotency TTL çok kısa,
- aynı intent için yeni key üretip protection'ı bypass etme,
- multi-region race,
- lock var ama persistent unique guard yok,
- request hash canonical değil,
- provider key ile internal key mapping kaybı.

## Observability

- idempotency hit rate,
- duplicate attempt blocked count,
- key conflict count,
- UNKNOWN retry blocked count,
- lock contention,
- duplicate provider reference detection.

## Production checklist

- operation-scoped deterministic keys,
- persistent unique guard,
- request hash,
- provider key mapping,
- UNKNOWN retry block,
- explicit TTL policy,
- replay/audit log,
- multi-node concurrency test.
