Spring Batch is the framework you reach for when a job is too big, too important, or too failure-prone to run as a plain loop — nightly ETL, statement generation, bulk imports. Interviewers use it to test whether you understand reliable bulk processing: transactions, restartability and scale, not just reading a file. This set covers the questions asked in intermediate Spring Boot rounds, using current Spring Batch 5 (Boot 3) configuration where the builders take the JobRepository and transactionManager directly.
What is Spring Batch and when would you use it?
Spring Batch is a framework for building robust batch jobs that process large volumes of data reliably. You reach for it when you need transactional chunking, restart-from-failure, skip/retry policies and audit metadata — features that are painful to build correctly by hand.
The distinction to draw is between "run some code on a schedule" and "process a million records reliably." A @Scheduled method can do the former. The moment you need to resume after a crash without reprocessing everything, skip a handful of bad rows without failing the whole run, and prove afterwards exactly what happened, you are rebuilding Spring Batch — so you use it instead.
Typical use cases are ETL, migrating data between systems, generating documents in bulk, and reconciliation jobs.
What are Job and Step?
A Job is the whole batch process; it is composed of one or more Steps executed in sequence (or in flows). Each Step is an independent phase with its own transaction behaviour and its own success/failure state. A Job orchestrates steps; a Step does the work.
The reason for splitting a job into steps is restartability and clarity: if step two fails, a restart can skip the already-completed step one and resume at step two. Each step also has its own metadata — read count, write count, commit count, skip count — which is what makes batch runs auditable.
Interview note: Follow-up: "how do steps share data?" Through the
ExecutionContext(job-level or step-level), a small persisted key-value store. It is meant for control state like a restart cursor, not for passing large datasets between steps.
What is chunk-oriented processing versus a tasklet?
Chunk-oriented processing reads items one at a time with an ItemReader, transforms each with an ItemProcessor, and after a configured chunk size accumulates, writes the whole chunk at once with an ItemWriter inside a single transaction. A tasklet is a simpler model: a single execute method that does an arbitrary unit of work, good for a one-off command like deleting files or running a stored procedure.
The chunk model is the heart of Spring Batch. Read and process happen per item; write and commit happen per chunk. That grouping is what gives you efficient bulk writes and bounded transaction sizes at the same time.
@Configuration
public class ImportJobConfig {
@Bean
Step importStep(JobRepository jobRepository,
PlatformTransactionManager txManager,
ItemReader<Customer> reader,
ItemProcessor<Customer, Customer> processor,
ItemWriter<Customer> writer) {
return new StepBuilder("importStep", jobRepository)
.<Customer, Customer>chunk(500, txManager) // chunk size + tx manager
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
@Bean
Job importJob(JobRepository jobRepository, Step importStep) {
return new JobBuilder("importJob", jobRepository)
.start(importStep)
.build();
}
}
Note the Spring Batch 5 shape: StepBuilder and JobBuilder take the JobRepository in their constructor, and .chunk(size, transactionManager) takes the transaction manager. In Boot 3 auto-configuration you no longer need @EnableBatchProcessing for the defaults.
What is the JobRepository and what are the metadata tables?
The JobRepository persists the runtime state of every job and step execution to a set of metadata tables — BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION, BATCH_STEP_EXECUTION and their parameter/context tables. This persisted state is what enables restartability, prevents duplicate runs, and provides the audit trail.
Every read count, write count, commit count, skip count and exit status lands in these tables. Because the state is durable, a crash does not lose the record of what completed — the framework can consult the repository on restart and decide what to resume.
Interview note: Trap: "what happens if the metadata tables are missing?" The job fails at startup because it cannot record executions. Spring Boot can auto-create them (via
spring.batch.jdbc.initialize-schema), and interviewers like candidates who know the metadata store is mandatory, not optional.
How do chunk size and commit interval affect a job?
The chunk size is the commit interval: after that many items are read and processed, the chunk is written and the transaction commits. A larger chunk means fewer commits and higher throughput but a bigger transaction and more work lost on a rollback; a smaller chunk commits more often, limiting loss but adding overhead.
Tuning it is a genuine trade-off, not a fixed number. Very large chunks can exhaust memory or hold locks too long; very small chunks waste time on transaction overhead. A common starting range is a few hundred to a few thousand, tuned against the writer's batching and the database.
What makes a job restartable, and how does restart work?
Because the JobRepository records how far each step got, a restart with the same identifying JobParameters resumes rather than restarting from scratch: completed steps are skipped, and an interrupted chunk step continues near the last committed chunk. Items already committed are not reprocessed.
The precision depends on the reader. A restartable reader (like a JDBC cursor/paging reader or a flat-file reader) saves its position in the ExecutionContext, so on restart it seeks back to roughly where it stopped. This is why "resume near where it stopped" is accurate — the resolution is the last committed chunk boundary, not the exact failed record.
Interview note: Follow-up: "can every step be restarted?" A step can be marked
allowStartIfComplete(true)to always rerun, or restart can be limited withstartLimit. By default a completed step is not rerun on restart, which is exactly the behaviour you usually want.
How do skip and retry work?
Skip lets a step tolerate a limited number of bad items — a malformed row is skipped and counted instead of failing the whole job. Retry re-attempts an operation that failed on a transient error, such as a deadlock or a brief network blip, before giving up. You configure both with fault-tolerant step builders, specifying which exceptions and what limits.
new StepBuilder("importStep", jobRepository)
.<Customer, Customer>chunk(500, txManager)
.reader(reader).processor(processor).writer(writer)
.faultTolerant()
.skip(FlatFileParseException.class).skipLimit(50)
.retry(DeadlockLoserDataAccessException.class).retryLimit(3)
.build();
The distinction interviewers want: skip is for bad data you accept losing; retry is for transient failures you expect to succeed on a second attempt. Using retry for genuinely bad data just wastes attempts; using skip for a transient outage silently drops good records.
Why do JobParameters make each run unique?
A JobInstance is identified by the job name plus its identifying JobParameters. Launching with the same identifying parameters is treated as the same instance and refused if it already completed successfully — this is what prevents accidentally running the same daily job twice. To run again, you supply a different identifying parameter.
JobParameters params = new JobParametersBuilder()
.addString("inputFile", "customers-2026-07-16.csv") // identifying
.addLong("run.id", System.currentTimeMillis()) // makes each run unique
.toJobParameters();
jobLauncher.run(importJob, params);
The common pattern is a meaningful identifying parameter (like the input file or a business date) so reruns of the same logical work are correctly blocked, plus a run id when you deliberately want a fresh instance. JobLauncher is the component that actually starts the job with those parameters.
Interview note: Trap: "why did my job say it was already complete and refuse to run?" Because you passed the same identifying parameters as a previous successful run — Spring Batch is protecting you from a duplicate. Add or change an identifying parameter to create a new instance.
How do you scale a Spring Batch job with partitioning?
Partitioning splits a step's input into partitions — for example ID ranges — and processes each partition in parallel using its own step execution, driven by a Partitioner and a partition handler. It is the standard way to parallelise, because each worker step gets its own reader/writer scoped to its slice, avoiding contention.
Other scaling options exist — multi-threaded steps, remote chunking, parallel flows — but partitioning is the most commonly discussed because it scales cleanly and each partition is independently restartable. The Partitioner decides how to divide the work; the framework runs the partitions concurrently and aggregates their results.
Interview note: Follow-up: "what do listeners add?"
JobExecutionListenerandStepExecutionListener(and chunk/item listeners) hook into lifecycle events for logging, notifications, setup and teardown — for example sending an alert inafterJobwhen the exit status is failed.
What interviewers really test
Spring Batch questions reward candidates who think in terms of reliability, not just data movement. The strongest answers connect chunk size to transaction boundaries, JobParameters to duplicate-run protection, and the JobRepository to restartability — and use the current Spring Batch 5 builders that take the JobRepository and transactionManager rather than the older @EnableBatchProcessing-plus-factory style.
To prepare, build one job end to end: a chunk step reading a CSV, a processor that transforms rows, a writer that inserts them, then deliberately kill it mid-run and restart to watch it resume. The Spring Boot learning path covers the surrounding data-access concepts, and this pairs well with the Spring Data JPA interview set since most batch jobs read or write through a repository layer. A mock interview focused on batch reliability is the fastest way to practise defending your chunk-size and restart decisions out loud.
Frequently Asked Questions
When should you use Spring Batch instead of a plain loop or scheduled job?
What is chunk-oriented processing?
What makes a Spring Batch job restartable?
Why do JobParameters matter for running a job twice?
How do you scale a Spring Batch job?
Want to Build Your Career in Java Full Stack with AI?
Join CodeBegun and train with working industry engineers — Discover CodeBegun's Java Full Stack track

