A poll-tick trace asks which outbox and consumer rows survive after retries and an uncertain acknowledgement.
Spring exercise: trace two poll ticks and a lost acknowledgement
First trace
Insert three due events, each reducing SKU-29 by one. Run a poll with limit two. Expect two DELIVERED rows, one PENDING row and stock 8. Run another poll. Expect all three delivered and stock 7. The checked batch test asserts these states. Now make the first transport call fail before consumer work. The event remains PENDING with one failure and a future due time; a later tick uses the same event ID.
The batch lesson explains why the third row waits. The retry lesson explains why an immediate tick should skip failed work.
Second trace
Let the consumer commit EVENT-61 but withhold the relay acknowledgement. Predict stock, applied-event count and outbox state before and after a later poll. The answer is stock 6 and one applied marker throughout; the outbox moves from PENDING to DELIVERED after the duplicate-safe callback.
Change one assumption at a time: remove the unique event key, then shorten the lease below transport latency. State which guard fails and what the next test should assert. Run the source-kit tests, then write a separate broker and target-database plan. The local exercise cannot prove that a process survives a real kill.
Checked source
mvn -q -Dtest=ScheduledOutboxPollerTest,OutboxRelayFlowTest testVerification boundary
ScheduledOutboxPollerTest.onePollProcessesOnlyItsBatchBudget and redeliveryAfterLostAcknowledgementDoesNotRepeatStockMutation. The excerpt is shortened or a labelled design sketch; the source kit contains the complete checked fixture.
Costs and limits
The exercise uses local H2 rows and a fake callback. There is no hosted judge, broker or deployment environment.
Common Mistakes
- Do not count a failed publish as delivered.
- Do not change an event ID to make a retry look new.
- Do not claim a cut-point simulation is a killed-process recovery test.
Read next
Spring outbox polling: cap work per tick and measure backlog age, Spring scheduled retries: leave failed work pending until its due time, Spring scheduled relay: recover when the consumer commits before acknowledgement, Spring relay integration tests: prove the boundaries H2 cannot.
