Build1 distinct publisher2 min readPublished
A nightly job that catches its own failure and returns cleanly is invisible to every dashboard you can bolt on afterwards, which is why the durable execution argument lands on the event log rather than the feature list.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
Trace the call in the guide's own sample. `jobLauncher.run` throws, the catch block logs the exception, and the method returns normally [16]. The comment sitting in that catch block says what follows: no alert, no retry, no escalation [16]. To the scheduler, the invocation completed, which is the "returns success" the guide puts at the centre of the problem [1]. Anything layered above consumes the same signal. Teams bolt on Actuator, custom logging and Micrometer, and the guide's own verdict is that by the time there is real observability it is a custom framework to maintain [9]. A framework you did not plan to write is still a framework you keep patched.
The interval is what costs money. The sample runs on cron `0 0 2 * * *`, once a night, chunk size 500 [15]. The guide says data corruption from concurrent runs can take weeks to surface [3]. Take two weeks as the low end of that: one run a night for fourteen nights is fourteen executions writing against corrupted state before anyone reads the evidence [1].
Durable execution changes where the history lives. Temporal records every state transition to an event log, and a crashed process is recovered by replaying that log and resuming from the point it stopped [5][6]. The observability is a byproduct of the recovery mechanism: a log detailed enough to reconstruct an execution is detailed enough to answer which step ran and how it ended [2]. Compare that with `BATCH_JOB_INSTANCE` and `BATCH_JOB_EXECUTION`, which the guide notes you manage, prune and keep consistent yourself [13].
The requirement the guide leaves implicit sits in your code. If resuming means replaying recorded state transitions through the same plain Java methods, those methods have to reach the same points in the same order when they are re-executed [3]. That constraint decides whether a given job is a straightforward port or a redesign.
The piece carries no measured numbers, only a before/after diagram and code [19], so nothing here transfers as a benchmark; what transfers is the failure taxonomy, and only if your jobs have the same shape. The guide is straight about that: `@Scheduled` is fine for one or two simple jobs, and the debt accumulates by the time a team has dozens [8]. In my context, a dozen-plus jobs whose only witness is a log line, a queryable execution history is worth the port. At three jobs, the scheduler you already run plus a lock library is the cheaper answer, and the guide concedes that the lock approach works [11].
Ranked by verification strength, evidence, and original report placement.
Scheduled jobs fail silently by catching exceptions, logging nothing meaningful, and returning success to the scheduler.
In the sample scheduler, jobLauncher.run is wrapped in a try/catch whose catch block logs "Invoice reconciliation failed" and carries the comment "No alert. No retry. No escalation."
In the guide's after-diagram, a Temporal scheduler triggers a workflow method that calls activities to read, process and write each chunk, with failures auto-retried, crashes replayed from the log and overlap prevented by a workflow ID lock.
Jobs run simultaneously because the previous execution had not finished before the next trigger fired and nobody configured @ScheduledLock.
Temporal is a durable execution platform: you write plain Java code (functions, loops, try/catch) and Temporal makes it fault-tolerant by recording every state transition to an event log.
If the process crashes mid-execution, Temporal replays the event log and resumes from exactly where it left off.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 27, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
The proxy in your call path decides whether @Transactional does anything at all1 distinct publisher
build
In Spring, the hook you need is decided by the clock, not by the name1 distinct publisher
build
A green @DataJpaTest can prove only that Hibernate handed back the same object1 distinct publisher
build
Shared memory in Java: the mmap is the easy half, the descriptor handoff is the work1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Inspectable code, unmeasured claims
Two different standards of proof sit side by side. The listings can be read for what they do — the swallowed exception, the PT2H lock, chunk size 500, five retry attempts — and need no outside confirmation. Everything above the code is assertion: dev.to reports no failure rates, no run times, no migration duration, and no one else has told this story.
Nobody deploys anything here
No team is named, no rollout described, no release, benchmark or usage figure attached to either the Spring Batch pipeline or its Temporal replacement. dev.to labels the invoice reconciliation job a representative pattern, and that is exactly what it is — an illustration, not a deployment we can count.
Elimination promised, cost unpriced
'Eliminates these problems' is a big verb for a piece with no numbers in it. The silent-failure diagnosis survives inspection and is genuinely underrated. But 'no state machine, no checkpoint tables, no retry logic' relocates work rather than deleting it: you inherit a Temporal cluster to operate and a replay determinism constraint to respect across deploys, and the guide flags neither while listing ShedLock's corrupted lock row as a mark against the incumbent.
One-sided by construction
Read from the shape of the piece, not from any disclosure. It is built as before/after with a single named commercial platform on the winning side, and that shape is what a comparison-titled dev.to post rewards. Nothing here states a relationship with Temporal and nothing rules one out; the asymmetry worth noting is that no comparable interest pulls toward Spring, so the critique of the incumbent goes unchallenged inside its own frame.
Sure what it argues, unsure it generalises
We can be firm about what this guide claims and shows, because all of it is on the page and the code is unambiguous. Whether dozens of @Scheduled jobs really rot the way described, and whether replay behaves as advertised under someone else's load and deploy cadence, is precisely what one tutorial with no measurements cannot settle.