Scenario: Post a journal exactly-once
Goal. Call a Lattice posting service (e.g. general-ledger journal) from an external system so that a network retry, a duplicated message, or a re-run never posts the document twice - and so you can validate the call before it commits and recover if a claim is left stranded.
When to use. Any create-then-post integration where the caller might send the same logical request more than once (almost all of them). If your source is a file, front this with Inbound file → posted document; the exactly-once guarantee below is the same either way.
The three guarantees
- Dry-run - a non-committing preview validates the request and returns the projected outcome without posting. (Posting preview)
- Exactly-once - the service stamps a self-describing idempotency claim (legal entity + created document identity) inside the create transaction; a second call with the same RequestId returns the first result instead of posting again.
- Self-healing - a scheduled sweep resolves any claim left stranded by a crash between create and post. (Idempotency reconcile runbook)
Prerequisites
- Security - grant the caller the service operation's Invoke privilege (see Security model); high-risk posting operations sit behind a dedicated duty.
- Number sequences - the journal's number sequences must be configured in the target legal entity (a missing/broken sequence is the classic "Voucher not specified" failure).
- A stable RequestId per logical request - the caller must send the same RequestId when it retries the same business request, and a new one for a genuinely new request. This is the key the whole guarantee turns on.
Steps
- Preview first (optional but recommended). Send the request with
PreviewModeset. The service validates and returns the projected result without consuming a number sequence, committing a document, or emitting an event. Number-consuming operations are capped to validation-only. - Post for real. Send the same request with
PreviewModeoff and a stableRequestId. The service (e.g.MGCLatticeGeneralLedgerJournalService.postGeneralJournal) creates the journal, stamps the idempotency claim in the same transaction, posts, and finalizes the claim. Payloads: Endpoint payload specification. - On a retry, just resend. An identical
RequestIdshort-circuits to the recorded outcome - no second post. A differentRequestIdis treated as a new request. ARequestIdbelongs to the operation that first used it: sending it to another operation is refused withDuplicateRequest.
How to verify
- The response carries the created document identity (journal number / voucher) and a posted flag.
- The document exists and is posted in the target legal entity.
- Re-sending the same
RequestIdreturns the same document identity and does not create a second journal. - Optionally use the Service test console (
MGCLatticeServiceTestConsole) to invoke the operation interactively, including in preview mode.
When it goes wrong
- Voucher / number-sequence errors - configure the journal's number sequences in the legal entity; these are environment setup, not a payload problem.
- A crash between create and post can leave a claim in
Processing. TheMGCLatticeIdempotencyReconciliationSweepbatch finds stranded self-describing claims and resolves each: Posted → finalize; NotFound → release; CreatedNotPosted → park for manual review. Run it on a schedule. Full runbook: Idempotency reconcile runbook. - A failed async post lands in the dead-letter queue; recover it from the Integration operations console exactly as in the inbound-file scenario. Replay reuses the original RequestId, so recovery is also exactly-once.