บทที่ 27 · Part 5 — From Model to Running System

Reliable Domain Processes

ดูแล process ข้าม Aggregate/Context ด้วย identity, outbox, idempotency, compensation และ reconciliation

Reliable Domain Processes

Transfer หนึ่งครอบ Intent, Risk, Funds, Provider และ Ledger ไม่มี Aggregate หรือ database transaction เดียวทำทั้งหมดได้ เมื่อ crash เกิดหลัง provider รับคำสั่งแต่ก่อนบันทึกผล คำว่า retry อย่างเดียวอาจ สร้างเงินซ้ำ DDD ต้อง model process identity, intermediate/unknown states, compensation และ repair เป็น business concepts

จบบทนี้คุณจะ

แยก local transaction จาก long-running business process ใช้ stable identity, idempotency, outbox/inbox, Saga/Process Manager, compensation และ reconciliation ตาม failure mode ออกแบบ human decision และ unknown outcome โดยไม่อ้าง exactly-once effect

Business Process มี Lifecycle

candidate TransferProcess/Process Manager ถือ:

Process ID
Intent ID
Policy decisions/versions
Reservation ID
Execution attempts/outcomes
Posting/reconciliation references
Current responsibility / deadline

มัน coordinate commands/facts แต่ไม่ควรเป็น Aggregate ใหญ่ที่แก้ state contexts อื่นโดยตรง

Stable Identity ทุก Boundary

BoundaryIdentity
user commandRequest/Intent ID
funds effectReservation/Posting Reference
provider requestIdempotency Key + Attempt ID
messageMessage/Event ID + causation
reconciliationCase/External Record ID

idempotency ต้องนิยามผลเดิมเมื่อ request ซ้ำและ reject key reuse กับ parameters ต่าง

Outbox/Inbox

Outbox แก้ local dual write: state+outbox ใน transaction เดียว relay ส่งภายหลัง อาจส่งซ้ำ Inbox/dedup ช่วย consumer แต่ business handler ต้อง idempotent

ไม่ได้ให้ exactly-once ทั้ง journey เพราะ external provider/human actions อยู่นอก transaction

Retry ตาม Failure

  • validation/domain rejection: ไม่ retry
  • known transient unavailable: backoff/jitter/budget
  • timeout after side effect possible: reconcile หรือ retry ด้วย same vendor idempotency contract
  • permanent decline: business outcome
  • unknown schema/contract: quarantine/alert ไม่วน

AWS Making Retries Safe ให้ first-party guidance เรื่อง idempotent API

แต่ละลูกศรข้าม boundary ต้องมี durable identity และ retry contract ส่วน Indeterminate หยุดการสร้าง side effect ใหม่จน reconciliation ให้ evidence ไม่ใช่ทางอ้อมไป Declined

Timeout ไม่เท่ากับ Failed

Provider อาจรับ request แล้ว response หาย Model INDETERMINATE, หยุด side effect ใหม่ และเปิด reconciliation ตาม contract ห้ามคืน funds/แจ้ง failed ทันทีโดยไม่มี evidence

Saga, Process Manager และ Compensation

Saga แบ่ง long transaction เป็น local transactions พร้อม compensating actions Process Manager เก็บ state/next action ของ flow Compensation เป็น business action เช่น Release Reservation หรือ Post Correction ไม่ใช่ rollback เวลา

บาง action ชดเชยไม่ได้ เช่น notification ถูกอ่านหรือ FX trade executed ต้อง model forward recovery

Reconciliation เป็น Safety Net

เปรียบเทียบ internal/external facts, classify exceptions, request evidence, apply approved correction, close with audit trail มี backlog owner/SLO อย่าทำเป็น cleanup job ที่แก้ rows เงียบ

Human in the Loop

manual review มี task identity, assignee/role, evidence, decision, expiry/escalation และ policy version event/process ต้องรอได้โดยไม่ lock database

Crash Matrix

Crash pointDurable evidenceSafe next action
before outbox commitnonecaller retry same command ID
after commit before relayoutboxrelay later
after provider effect before responseprovider/idempotency unknownquery/reconcile
after outcome before postingexecution factidempotent posting command
after posting before displayledger factrebuild projection

แบบฝึกปฏิบัติ: Indeterminate Transfer

สร้าง process state machine และ crash matrix อย่างน้อย 8 จุด ระบุ identity, authority, retry class, compensation, reconciliation owner, human step และ customer-visible wording

Acceptance: replay ทุก crash ไม่สร้าง provider effect หรือ ledger posting ซ้ำ และ display cache ไม่ใช้ตัดสิน

รายการตรวจสอบ

  • Business process มี identity/lifecycle
  • Local vs long transaction แยก
  • Idempotency ทุก side-effect boundary
  • Outbox consumer ยังรับ duplicate
  • Retry ตาม failure class
  • Compensation เป็น business action
  • Unknown มี reconciliation owner
  • Human step durable/auditable

สรุปบทนี้

Process ข้าม contexts ต้อง model uncertainty และ recovery เป็นส่วนของ domain Stable identity, outbox/idempotency, Process Manager, compensation และ reconciliation แก้ failure คนละชนิด ไม่มี pattern เดียวให้ exactly-once business outcome

อ่านเพิ่มเติม