I have a quite basic step in a Spring Batch job (using Java config):
@Bean
public Step step1() {
return stepBuilders.get("stepName")
.<Object1, Void>chunk(50)
.reader(reader(inputResource(null))
.processor(processor())
.listener(stepLogger())
.transactionAttribute(transactionTimeoutAttribute(null))
.build();
}
.......
@Bean
@StepScope
public StepExecutionListener stepLogger() {
return new StepLogger();
}
@Bean
@StepScope
public TransactionAttribute transactionTimeoutAttribute(
@Value("#{jobParameters[transactionTimeout]}") Integer timeout) {
timeout = timeout != null ? timeout : DEFAULT_TRANSACTION_TIMEOUT;
RuleBasedTransactionAttribute transactionAttribute = new RuleBasedTransactionAttribute();
transactionAttribute.setTimeout(timeout);
return transactionTimeout;
}
As you can see, it's a requirement that the transaction timeout can be given as a job parameter. This works flawlessly, and if I set the transactionTimeout job parameter too low, the job execution will fail as transactions time out before the chunk completes.
However, if I try to tack on fault tolerance (to be able to skip a certain amount of failed elements), everything falls apart. When I add faultTolerant() to the step config to be able to specify the skip policy etc, like this:
@Bean
public Step step1() {
return stepBuilders.get("stepName")
.<Object1, Void>chunk(50)
.reader(reader(inputResource(null))
.processor(processor())
.faultTolerant()
.listener(stepLogger())
.transactionAttribute(transactionTimeoutAttribute(null))
.build();
}
Spring can no longer start the context (on Jetty for now), and just throws the following exception on startup:
BeanCreationException: Error creating bean with name 'scopedTarget.transactionTimeoutAttribute': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
What is the correct way of specifying both a transaction attribute and skip policy of a step in Spring Batch using Java Config?
EDIT: Just to make the question a bit more understandable, my requirement is to make a fault tolerant step where the transaction timeout is configurable as a job parameter. For non-fault tolerant step, that's not a problem, just make a step scoped TransactionAttribute bean with the job parameters wired in. But the FaultTolerantStepBuilder handles the transaction attribute differently (it basically merges the given transaction attribute with its internal one), so the step scope is not available. How can I use the job parameters to configure the transaction attribute of a fault tolerant step (Java config)?