块中的Spring Batch异常

时间:2012-06-19 18:48:29

标签: java spring-batch chunks

我有一个弹出批处理作业,它有多个步骤。

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

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

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

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

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

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

  3. 注意: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并且我抓住它,因此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 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

检查loanValidationService.validate

的事务传播选项

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

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

如果chunk的交易在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
        }
    }