首页 文章

块中的Spring Batch异常

提问于
浏览
2

我有一个 spring 批处理作业,它有多个步骤 .

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

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

据我了解,现在每一条记录都会发生

开始交易(读 - 处理 - 写)提交Tx

  • 我的问题是想象它处理了6条记录,现在使用第7条记录它在ItemProcessor实现中得到一个异常,它试图回滚但由于处于未知状态的事务而无法回滚

  • 即使它无法回滚第7条记录的tx,它也根本不会处理第8,9,10条记录而且作业已停止 .

注意:ItemProcessor实现是调用服务(@Service annotated),使用@Transactional(readOnly = false)注释将其标记为事务性 .

请提出解决方案 .

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

即使配置了可跳过的异常类,这也不起作用 .
为了解释更多我在Item Processor中得到Persistence Exception并且我 grab 它,因此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

2 回答

  • 2

    在loanValidationService.validate检查事务传播选项

    从“标记为rollbackOnly的事务”中猜测,“在步骤执行数据已更新时提交失败”

    当前事务已回滚,父事务应该提交但事务已经结束 .

    如果chan的事务在LoanValidationService.validate中是相同的

    将传播选项更改为REQUIRES_NEW

    以下文章可能有助于理解元数据的事务 . 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
            }
        }
    
  • 2

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

    如果您知道异常的根本原因,则可以通过 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>
    

    由于将跳过给定的异常类及其子类,您甚至可以尝试 java.lang.Exception

相关问题