2015-01-07 4 views
0

Spring Batch 애플리케이션은 실패한 작업을 재시작 할 때 동일한 레코드를 다시 처리하므로 중복 행이 발생하므로이를 피하는 방법을 알고 싶습니다.Spring Batch : 작업 재실행 후 중복 행

배치 작업을 시작하는 스프링 통합 폴러는 2 시간마다 실행되도록 구성됩니다. 두 번째 실행될 때 작업 매개 변수는 동일하지만 이전 실행이 실패한 경우 (예 : DataTruncation 예외로 인해) Spring Batch는 작업이 이미 완료되었다고 불평하지 않습니다.

오류가 발생하면 수십만 개의 레코드가 이미 처리되어 원본 테이블에서 대상 테이블로 복사됩니다. 이후에 작업이 실행되면 동일한 행이 대상 테이블에 복사되어 중복됩니다. 따라서 작업이 다시 시작되지 않고 처음부터 다시 시작된 것 같습니다.

스프링 배치 데이터베이스는 Derby (파일 기반)이며 응용 프로그램이 시작될 때 설정되며 실제 매개 변수로 작업을 다시 실행할 수 있기 때문에 실제 응용 프로그램을 다시 시작하는 사이에는 상태가 유지되지 않습니다. 그러나 한 응용 프로그램을 실행하면 상태가 유지됩니다. 예를 들어 작업이 성공적으로 완료되면 다음 번 폴러가 예외를 실행할 때 해당 매개 변수가있는 작업이 이미 완료되었으므로 예외가 발생합니다. 절 BY ORDER를 포함

<batch:job id="publisherJob" > 
    <batch:step id="step1"> 
     <batch:tasklet > 
    <batch:chunk reader="itemReader" processor="itemProcessor" 
       writer="itemWriter" commit-interval="${...}" /> 
     </batch:tasklet> 

     <batch:listeners> 
     ... 
     </batch:listeners> 
</batch:job> 

<bean id="itemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="sql" value="select ${...} from ${...} where ${...}" /> 
    <property name="rowMapper" ref="rowMapper" /> 
</bean> 

을 :

우리가 할 일은 다음과 같이 정의입니다.

Spring Batch는 처리가 실패한 상태를 유지하고 (소스 테이블의 오류가 수정 된 경우) 그 지점부터 진행하므로 중복 행을 방지합니다. 이것이 일어나기 위해서 무엇을 구성해야합니까?

감사

답변

1

스프링 배치는 많은 기록하지 특히 ​​어떤 것들, 처리 된 방법을 기억 점에서 상태를 유지한다. 따라서 실행 순서에 따라 항목의 순서가 재현 될 수 있도록 보장해야합니다. 따라서 실행 1에서 100 개의 레코드를 처리하고 실패 할 경우 실행 2의 처음 100 개의 레코드를 건너 뛸 때 해당 항목이 100 건너 뛸 레코드. JdbcCursorItemReader에 대한 구성을 제공하지 않았지만 귀하의 SQL에서 주문을 사용하지 않는다고 가정합니다. 재시작 가능성을 원할 경우 항목의 순서를 보장 할 수있는 방법이 필요합니다. SQL에서 order by를 사용하는 것이이 작업을 수행하는 가장 쉬운 방법입니다 (필요한 경우 프로세스 표시기 패턴 사용과 같은 다른 방법이 있습니다).

+0

감사합니다. JdbcCursorItemReader에서는 ORDER BY 절을 정의합니다. 그래서 우리는 항상 재실행 할 때마다 대상 테이블에 정확히 같은 행을 삽입해야합니다. 항상 중복되는 동일한 세트입니다. 따라서 Spring Batch는 항상 소스 결과 집합의 첫 번째 행부터 시작하는 것으로 보입니다. – user1052610

+0

<배치 : 작업 ID = "publisherJob"> <배치 스텝 ID = "1 단계"> <배치 : 릿> \t <배치 : 청크 리더 = "itemReader"프로세서 = "itemProcessor" 라이터 = "itemWriter" 커밋 간격 = "$ {...}"/> <배치 : 청취자> \t ... user1052610

+0

원래의 질문으로 업데이트 – user1052610

관련 문제