Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring exercise: predict outbox state across a lost acknowledgement

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A lost acknowledgement exercise asks which rows change when the consumer commits but the relay cannot mark the outbox delivered.

Download Spring source kit

Run the sequence

Accept EVENT-31 for two units of SKU-17. Let worker A claim it and call the consumer successfully. Stock moves from 10 to 8, and applied_event contains EVENT-31. Stop before acknowledgement. At the lease expiry, worker B reclaims the PENDING row and calls the consumer with the same event ID. Predict the second stock balance, applied_event count, and whether B may acknowledge.

The answer is 8, one, and yes if B still owns an unexpired claim. The second consumer call hits the unique event-ID key and skips the stock update. Worker A must not acknowledge after B has taken the claim. The event ledger and fencing token protect different rows.

Change one assumption

Remove the applied_event unique key. The second call may subtract stock again. Move the applied_event insert into a separate committed transaction before the stock mutation. A business failure can then make a later valid retry look like a duplicate. Predict the final rows before running the checked tests.

Extend the kit with a test for a failed external publish after claim, then state what cannot be proved without a broker. A passing H2 test is evidence for local SQL state transitions only.

Checked source

bash
mvn -q -Dtest=OutboxRelayFlowTest test

Verification boundary

OutboxRelayFlowTest has seven local tests in the downloadable Spring source kit. The excerpt is shortened; the kit contains the complete test.

Costs and limits

This is a self-check backed by an in-process source kit, not a hosted judge. The lost-acknowledgement scenario is reasoned from separately checked claims and duplicate calls; no process is actually killed.

Common Mistakes

  • Do not change the event ID when replaying the same event.
  • Do not assume a failed acknowledgement means the consumer rolled back.
  • Do not equate a passed local exercise with target-system recovery.

Read next

Spring relay failure trace: inspect persisted state at each cut point, Spring consumer idempotency: reserve an event ID with the stock mutation, Spring outbox claims: lease expiry and token-fenced acknowledgement, Spring outbox transaction boundaries: where atomicity ends.

spring
spring-boot
outbox
Storage details