2012-06-19 93 views
2

我有一個有多個步驟的彈簧批處理作業。塊中的彈簧批異常

第1步:從數據庫加載10條記錄。 (微進程做這項工作)

第2步:在此處配置使用ItemReader,ItemProcessor中,ItemWriter實現與組塊爲主的加工提交-interval = 1

現在我明白了,對每條記錄會發生這種情況

BEGIN TRANSACTION(讀 - 處理 - 寫)提交的Tx

  1. 我的問題是想象它處理六個記錄,現在用7號記錄它得到的ItemProcessor中執行一個例外,它試圖rollbac k但由於交易處於未知狀態而無法回滾

  2. 即使無法回滾tx的第7條記錄,它也不會處理第8,9,9條記錄,並且作業處於STOPPED狀態。

注:ItemProcessor中實現呼叫服務(@Service註釋),它使用@Transactional(唯讀= 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; 
} 

即使配置了該不起作用可跳過的異常類。更
要說明一點,我得到的項目處理器持久性的異常,我抓住它,因此春季批次執行的作家,但作家執行後,我得到以下

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

對於您的兩個問題外,跳過發生異常在起訴階段將解決你的問題。

如果您知道異常的根本原因,則可以使用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

+0

也許你可以分享你的處理器代碼。這可能有助於通過http://stackoverflow.com/a/7552940/305142 –

+0

編輯我的原始問題處理器代碼。 dataLoadLoanManagementService.createLoan(loanApplication,user,loanStatus); – Rishi

+0

你可以在catch塊的末尾添加'throw le;'line catch(Exception le)'你應該爲你的情況拋出這個異常,以防止交易不景氣 –

2

檢查事務傳播選項在loanValidationService.validate

猜出「標記爲rollbackOnly交易」,「提交失敗而步驟執行數據已更新」

當前事務已回滾並且父事務應提交但事務已結束。

如果塊的事務在LoanValidationService處相同。驗證

更改傳播選項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 
     } 
    }