【问题标题】:Spring Batch Exception in Chunk块中的 Spring Batch 异常
【发布时间】:2012-06-21 20:56:34
【问题描述】:

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

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

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

现在据我了解,每条记录都会发生这种情况

开始事务(读取 - 处理 - 写入)提交 Tx

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

    李>
  2. 即使它无法回滚第 7 条记录的 tx,它也不会处理第 8、9、10 条记录,并且作业已停止。

注意:ItemProcessor 实现正在调用使用@Transactional(readOnly=false) 注释标记为事务性的服务(@Service 注释)。

请提出解决方案。

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

即使配置了可跳过的异常类,这也不起作用。
为了解释更多,我在项目处理器中得到持久性异常并捕获它,因此 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

【问题讨论】:

    标签: java spring-batch chunks


    【解决方案1】:

    在loanValidationService.validate 中检查交易传播选项

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

    当前事务已回滚,父事务应提交但事务已结束。

    如果块的事务在 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

      【讨论】:

      • 也许你可以分享你的处理器代码。顺便说一句,这可能会有所帮助stackoverflow.com/a/7552940/305142
      • 用处理器代码编辑了我原来的问题。发生异常 dataLoadLoanManagementService.createLoan(loanApplication, user,loanStatus);
      • 你能在你的catch块的末尾添加throw le;行吗catch(Exception le)你应该为你的情况抛出这个异常以防止交易不一致
      猜你喜欢
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      • 2014-04-26
      • 2013-07-26
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 2012-06-16
      相关资源
      最近更新 更多