简体   繁体   English

批量中的Spring Batch异常

[英]Spring Batch Exception in Chunk

I have a spring batch job which has multiple steps. 我有一个春季批处理工作,其中包含多个步骤。

Step 1 : Loads 10 records from the database. 步骤1:从数据库中加载10条记录。 (Tasklet does that job) (Tasklet可以完成这项工作)

Step 2: Chunk Oriented processing in configured here using ItemReader,ItemProcessor,ItemWriter implementations with commit -interval =1 第2步:使用提交-interval = 1的ItemReader,ItemProcessor,ItemWriter实现在此处配置块处理

Now as I understand , for every record this would happen 据我了解,每笔记录都会发生

Begin Transaction ( Read - Process - Write ) Commit Tx 开始事务(读取-处理-写入)提交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 我的问题是想象它处理了六个记录,而现在有了第7条记录,它在ItemProcessor实现中出现了异常,它试图回滚,但由于事务处于未知状态而无法回滚

  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. 即使它无法回滚第7条记录的tx,也根本不会处理第8、9、10条记录,并且作业已停止。

Note: ItemProcessor implementation is calling services (@Service annotated) which are marked as transactional using @Transactional(readOnly=false) annotation. 注意:ItemProcessor实现正在调用使用@Transactional(readOnly = false)注释标记为事务性的服务(已注释@Service)。

Please suggest the solution. 请提出解决方案。

ItemProcessor Code Below 下面的ItemProcessor代码

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 为了进一步说明,我在Item Processor中获得了Persistence Exception并捕获了它,因此Spring Batch执行了writer,但是在执行完writer之后,我得到了下面的异常

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. 如果您知道异常的根本原因,则可以通过skippable-exception-classes元素来配置它。 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 由于将跳过给定的异常类及其子类,因此您甚至可以尝试java.lang.Exception

check transaction propagation option at loanValidationService.validate 在loanValidationService.validate检查交易传播选项

Guess from "Transaction marked as rollbackOnly", "Commit failed while step execution data was already updated" 从“将事务标记为rollbackOnly的事务”中猜测,“在步骤执行数据已更新时提交失败”

Current transaction was rollbacked and parent Transaction should be commit but transaction already over. 当前事务已回滚,应提交父事务,但事务已结束。

if chunk's transaction is same at LoanValidationService.validate 如果块的事务在LoanValidationService.validate处相同

change propagation option to REQUIRES_NEW 将传播选项更改为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/ 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
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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