داده، SQL، قراردادها و ماشین حالت · فصل ۶ — Event، Outbox، Reconciliation و State Machine · 75
Event-driven Design and Idempotent Receipt
Design one bounded event consumer with a durable receipt key, duplicate handling and explicit ordering limits, then prove a redelivery does not repeat the owned side effect. میتواند «Event-driven Design و Idempotent Receipt» را برای یک domain محدود مدل کند و constraint، compatibility یا recovery evidence لازم را مشخص کند.
Lesson summary
Design one bounded event consumer with a durable receipt key, duplicate handling and explicit ordering limits, then prove a redelivery does not repeat the owned side effect.
میتواند «Event-driven Design و Idempotent Receipt» را برای یک domain محدود مدل کند و constraint، compatibility یا recovery evidence لازم را مشخص کند.
This lesson produces
میتواند «Event-driven Design و Idempotent Receipt» را برای یک domain محدود مدل کند و constraint، compatibility یا recovery evidence لازم را مشخص کند.
Who it is for
Foundation
Worked baseline, explicit evidence table, local fixture and one guided failure probe.
Repair
Reduce to one broken contract/protocol assumption, observe it, repair it, then restore the full case.
Experienced
Compress introductory syntax; require independent compatibility/reliability decision, negative evidence and residual-limit statement.
Prerequisites
This lesson owns one bounded question: how can one event consumer survive redelivery without repeating its owned side effect, while keeping ordering limits explicit? The evidence artifact is Idempotent Event Receipt Record v1. It is not a claim of global exactly-once delivery, total ordering, or broker-specific guarantees.
1. The owned outcome
You will model one inventory projection that consumes ReservationAccepted. The event producer, event channel, event consumer, business entity, stable receipt key, version, owned side effect, duplicate rule, ordering rule, and residual risk must all be visible. The decisive evidence is local and inspectable.
2. Event boundary before implementation
An event-driven architecture separates producers from consumers through an event channel. That decoupling is useful, but it moves delivery, retry, ordering, and eventual-consistency concerns into reliability design. A green consumer run does not prove the channel is globally reliable.
For this lesson the bounded chain is:
producer fact -> event channel -> delivery -> stable receipt key -> atomic receipt + owned effect -> duplicate/out-of-order decision -> acknowledgement -> evidence
3. Stable receipt key
The receipt key must identify the logical unit of work and survive redelivery. In the fixture, transport delivery IDs change across attempts, but the event key remains inventory:sku-42:reservation:R-1001. That stable event key—not delivery_id—is the deduplication identity.
A transient delivery token may be useful operational metadata, but a transport delivery ID is not automatically the correct business idempotency key.
4. Idempotent effect
After the first accepted event, stock moves from 100 to 97. A redelivery with the same stable receipt key and a different transport delivery ID must be classified as DUPLICATE_SUPPRESSED, keep stock at 97, and keep the logical receipt count at one.
This is bounded idempotency for one owned side effect. It does not make downstream systems idempotent.
5. Atomic receipt and effect
The safe local design couples receipt creation and the owned state mutation inside one atomic boundary. In the synthetic fixture, the atomic path commits both or neither. The deliberate non-atomic variant applies the stock decrement and crashes before recording the receipt. A redelivery can then apply the decrement again. The expected classification is NON_ATOMIC_DUPLICATE_RISK.
That observation demonstrates a local failure window; it is not a global distributed transaction guarantee.
6. Deduplication is not ordering
A consumer can be perfectly duplicate-free and still apply stale data. After version 10 is accepted for sku-42, a distinct event with version 9 is not a duplicate. It is stale. The correct bounded outcome is STALE_EVENT_REJECTED, with the owned state unchanged.
The ordering rule is explicit: for this projection, a new event may mutate state only when its entity version is greater than the accepted current version.
7. Baseline probe
The first probe is baseline_first_delivery:
- event key:
inventory:sku-42:reservation:R-1001 - transport delivery ID:
delivery-A - entity version:
10 - stock delta:
-3
Expected class: RECEIPT_COMMITTED_EFFECT_APPLIED.
8. Redelivery probe
The second probe is duplicate_redelivery_new_transport_id. It reuses the same event key and version but changes transport delivery ID to delivery-B. Expected class: DUPLICATE_SUPPRESSED. The stock and entity version must not change after the first accepted effect.
9. Crash-window probe
The third probe is non_atomic_crash_window. It intentionally uses a broken variant where the business effect can become visible before the receipt is durable. The first attempt crashes after decrementing stock; the redelivery sees no receipt and decrements again. Expected class: NON_ATOMIC_DUPLICATE_RISK.
Preserve this negative evidence. Do not hide it after the repair.
10. Stale-version probe
The fourth probe is stale_lower_version. It uses a different stable event key with version 9 after version 10 has already been accepted. Expected class: STALE_EVENT_REJECTED. This is the evidence that deduplication alone does not solve stale or out-of-order events.
11. Evidence completeness probe
The fifth probe removes Residual Risk from an otherwise plausible record. Expected class: EVIDENCE_INCOMPLETE. The technical run is not enough if the final evidence cannot state what remains unproven.
12. Idempotent Event Receipt Record v1
For each decisive case record:
- Event Key
- Business Entity
- Version
- Delivery Attempt
- Receipt State
- Side Effect
- Duplicate Decision
- Ordering Decision
- Evidence
- Residual Risk
Keep vendor facts, local observations, and your engineering inference separate.
13. What the sources do and do not prove
Three official Azure pages define the current source boundary. The event-driven architecture guidance supports producer/channel/consumer decoupling plus delivery, ordering, and eventual-consistency challenges. The Idempotent Consumer pattern supports a stable identifier and a durable record of processed messages under duplicate delivery. Retry guidance supports the relationship between retry and idempotency.
These sources do not prove that the bundled fixture has exactly-once delivery or that any specific broker provides global ordering.
14. Non-goals and forbidden shortcuts
Do not conclude any of the following from this lesson:
- Event-driven architecture guarantees ordering or exactly-once side effects.
- Broker-level duplicate suppression removes the need for idempotent consumer design.
- A transport delivery ID is always the correct business idempotency key.
- Deduplication alone solves stale or out-of-order events.
- A green local run proves production reliability.
15. Transfer: webhook retry
A webhook-like consumer receives retries with stable request_id=req-4401, but each attempt has a different transport delivery ID. Choose the receipt key and the stale-update rule independently. Your decision must explain why the stable business request ID survives redelivery and how a lower resource version is rejected even when its request ID is new.
16. Assessment boundary
A passing answer needs positive, negative, and changed-context evidence. Happy-path success alone fails the evidence standard. You must defend the bounded decision against the shortcut that broker deduplication or retry configuration alone solves the consumer's side-effect problem.
17. Freshness and review
The current source boundary contains three official Microsoft Learn pages. Same-locator recheck on 2026-09-16 found no material drift in the claims used here. The Bible review trigger remains 2026-12-31. If vendor guidance changes, recheck the claim boundary before changing the lesson scope.
18. Final bounded decision
The local fixture can prove that one stable receipt key suppresses a redelivery, that one deliberately non-atomic design exposes a duplicate-side-effect gap, and that a stale version requires an ordering rule separate from deduplication. It cannot prove broker-wide exactly-once semantics, total ordering, production topology safety, or downstream idempotency. The learner owns the final residual-risk decision.
Assessment
There is no answer key in this lesson pack; answer it yourself and mark honestly. "Needs review" sends the lesson to your review queue.
DAT-017-S1 retrieval
State the bounded receipt-key rule and one non-goal.
DAT-017-S2 application
Run the baseline and duplicate probes and record evidence.
DAT-017-S3 diagnosis
Explain the non-atomic crash-window result without overclaiming.
DAT-017-S4 decision
Defend why deduplication and ordering require separate rules.
DAT-017-S5 transfer
Choose the webhook receipt key and stale-update rule independently.
Assessment rubric
Critical dimensions: bounded model correctness; evidence quality; scope discipline; transfer independence. Happy-path-only proof is insufficient.
References & freshness
Case studies
Lesson visuals
Lab files
Lesson media & slides
Teaching files (download)