简体   繁体   中英

Spring Batch Exception in Chunk

I have a spring batch job which has multiple steps.

Step 1 : Loads 10 records from the database. (Tasklet does that job)

Step 2: Chunk Oriented processing in configured here using ItemReader,ItemProcessor,ItemWriter implementations with commit -interval =1

Now as I understand , for every record this would happen

Begin Transaction ( Read - Process - Write ) Commit Tx

  1. My problem is imagine it processed six records and now with the 7th Record it got an exception in the ItemProcessor Implementation, It tries to rollback but not able to rollback due to transaction in unknown state

  2. Even if it is not able to rollback tx for 7th record it does not processes 8th,9th,10th record at all and job is STOPPED.

Note: ItemProcessor implementation is calling services (@Service annotated) which are marked as transactional using @Transactional(readOnly=false) annotation.

Please suggest the solution.

ItemProcessor Code Below

public Long process(LoanApplication loanApplication)throws Exception {
    Long createLoan = null;
    LoanStatus loanStatus = null;
    StaffUser user = staffUserService.getStaffUserByName(Constants.AUTO_USER);
    String notes = null;
    try{
        try{

            loanValidationService.validate(loanApplication);

            loanStatus=LoanStatus.U;

        }catch(LoanValidationException e){
            loanStatus=LoanStatus.UC;
            notes=e.getMessage();
        }

        dataLoadLoanManagementService.setText(notes);
        createLoan = dataLoadLoanManagementService.createLoan(loanApplication, user,loanStatus);
    }catch(Exception le){
        logger.error("Error creating the loan application ;  Parent Application Ref : " 
            + loanApplication
            + " with status as " +(loanStatus!=null ?loanStatus.getStatus():loanStatus)
            +"\n"
            +" School Ref :"
            + loanApplication.getSchoolRef()
            +"\n"
            +" Client Details :"
            +loanApplication.getClientDetails()
            + "Error Details: " + ExceptionUtils.getStackTrace(le));


    }   
    return createLoan;
}

Even with Skippable Exception Classes configured this does not work.
To explain bit more i get Persistence Exception in Item Processor and i catch it , therefore Spring batch executes the writer but after writer execution i get the exception below

INFO  06-21 11:38:00 Commit failed while step execution data was already updated. Reverting to old version.  (TaskletStep.java:342) 
ERROR 06-21 11:38:00 Rolling back with transaction in unknown state  (TaskletStep.java:351) 
ERROR 06-21 11:38:00 Encountered an error executing the step  (AbstractStep.java:212)
org.springframework.transaction.TransactionSystemException: Could not commit JPA   transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly

For both of your questions, skipping the exception occured during the prosessor phase will solve your problems.

This may be configured by skippable-exception-classes element if you know the root cause of the exception. For example, if you get a divide by zero exception during the processor phase and do want to neglect it, a sample configuration might be:

<chunk reader="reader" processor="processor" writer="writer" 
commit-interval="1" >
<skippable-exception-classes>
<include class="java.lang.ArithmeticException" />
</skippable-exception-classes>
</chunk>

Since the given exception class and its subclasses will be skipped, you may even try java.lang.Exception

check transaction propagation option at loanValidationService.validate

Guess from "Transaction marked as rollbackOnly", "Commit failed while step execution data was already updated"

Current transaction was rollbacked and parent Transaction should be commit but transaction already over.

if chunk's transaction is same at LoanValidationService.validate

change propagation option to REQUIRES_NEW

following article may help to understand metadata's transaction. http://blog.codecentric.de/en/2012/03/transactions-in-spring-batch-part-1-the-basics/

    class LoanValidationServiceImpl implements LoanValidationService {
        @Trasnactional(propagation=REQUIRES_NEW, rollbackFor=Exception.class)
        validate(LoanApplication loanApplication) {
             // business logic
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM