java 块中的 Spring Batch 异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11107409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:49:57  来源:igfitidea点击:

Spring Batch Exception in Chunk

javaspring-batchchunks

提问by Rishi

I have a spring batch job which has multiple steps.

我有一个包含多个步骤的春季批处理作业。

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

步骤 1:从数据库加载 10 条记录。(Tasklet 完成这项工作)

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

第 2 步:在此处使用 ItemReader、ItemProcessor、ItemWriter 实现配置的面向块的处理,commit -interval =1

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

  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.

  1. 我的问题是想象它处理了 6 条记录,现在第 7 条记录在 ItemProcessor 实现中出现异常,它尝试回滚但由于事务处于未知状态而无法回滚

  2. 即使它无法回滚第 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

即使配置了可跳过的异常类,这也不起作用。
为了多解释一点,我在项目处理器中得到持久性异常并捕获它,因此 Spring 批处理执行编写器,但在编写器执行后我得到以下异常

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

回答by Serkan Ar?ku?u

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

对于您的两个问题,跳过prosessor阶段发生的异常将解决您的问题。

This may be configured by skippable-exception-classeselement 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:

skippable-exception-classes如果您知道异常的根本原因,这可以由元素配置。例如,如果您在处理器阶段遇到除以零异常并且确实想忽略它,示例配置可能是:

<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

回答by hothead

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
        }
    }