1

In some batch job, i call a method from a class, that's marked with:

@Transactional(propagation = Propagation.REQUIRED, noRollbackFor = {
        Fault.class,
        AnotherFault.class
})
public class ...

And, when i call this method, and an exception throws i get exception:

00:29:25,765 ERROR [org.springframework.batch.core.step.AbstractStep] (executor-2) Encountered an error executing the step: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly

To solve this problem, i try use nested transactions. Jpa don't support nested transactions, so i create dummy class with:

@Transactional(propagation = Propagation.NOT_SUPPORTED)

and call from this dummy class without transactions, my method with transactions and rollbackFor.

Result of this described here: http://postgresql.1045698.n5.nabble.com/locking-problem-in-jdbc-driver-td2174897.html

So, another way to resolve this problem - configure job:

<batch:step id="parse-step">
    <batch:tasklet>
        <batch:chunk reader="xmlCommonJob.Reader"
                     processor="xmlCommonJob.Processor"
                     writer="xmlCommonJob.Writer"
                     commit-interval="2"/>
        <batch:no-rollback-exception-classes>
            <batch:include class="com.my.common.services.fault.Fault"/>
            <batch:include class="com.my.common.services.fault.AnotherFault"/>
        </batch:no-rollback-exception-classes>
    </batch:tasklet>
    <batch:next on="FAILED" to="file-failed-step"/>
    <batch:next on="COMPLETED" to="file-success-step"/>
</batch:step>

all to no avail.

Any idea?

indiv
  • 17,306
  • 6
  • 61
  • 82
Ruslan
  • 14,229
  • 8
  • 49
  • 67

2 Answers2

2

In Spring Batch we shouldn't catch exceptions in steps, for log in database, we should use listener:

    <batch:step id="parse-step">
        <batch:tasklet>
            <batch:chunk reader="xmlCommonJob.Reader"
                         processor="xmlCommonJob.Processor"
                         writer="xmlCommonJob.Writer"
                         commit-interval="1">
            <batch:skip-policy>
                <bean class="org.springframework.batch.core.step.skip.AlwaysSkipItemSkipPolicy" scope="step"/>
            </batch:skip-policy>
            </batch:chunk>
        </batch:tasklet>
        <batch:next on="FAILED" to="file-failed-step"/>
        <batch:next on="COMPLETED" to="file-success-step"/>
        <batch:listeners>
            <batch:listener ref="parseStepExecutionListener"/>
            <batch:listener ref="parseStepSkipListener"/>
        </batch:listeners>
    </batch:step>

in bean parseStepSkipListener i log exceptions with logger and can save info to database.

Ruslan
  • 14,229
  • 8
  • 49
  • 67
1

It is not recommended to annotate business methods with @Transaction when using Spring Batch. Spring Batch handles transaction semantics within the framework so adding @Transactional can cause issues. I'd recommend removing the annotation and letting Spring Batch handle it.

Michael Minella
  • 20,843
  • 4
  • 55
  • 67
  • I can remove @Transaction from my classes, but can't from business methods. I work around, and solve this problem. Soon i describe how i do this. – Ruslan Dec 12 '13 at 23:21