2017-11-27 21 views
0

스프링 배치로 일괄 처리를 작성하고 있습니다. 필자는 데이터 원본 (Oracle 데이터베이스)에서 대상 (Kafka 브로커)까지 약 2 000 000 개의 레코드를 이동해야합니다. 나는 ItemReader 나는이 작업을 위해 선택해야하는 주저 해요 :스프링 배치 JdbcCursorItemReader 또는 RepositoryItemReader?

  • JdbcCursorItemReader : 나는 올바르게 하나에 의해 레코드의 ALL의 결과 집합을 반복 할 것이다 커서, 하나를 엽니 다 이해한다면 , 성능은 문제가되지 않습니다. 후드 데이터베이스에서는 쿼리가 실행될 때 을 만족하는 레코드의 스냅 샷을 유지합니다. 여기서는 절이 사용됩니다.

  • RepositoryItemReader가 : 덜 확대됨 수 있습니다, 분할 페이징 메커니즘을 기반으로, 각 페이지에 대해 쿼리가 실행됩니다 동안 데이터베이스에 기록 할 수있는 몇 가지 기록을 ommiting의 가능성이있는 같으면, 2 개 000 000 레코드 가져 오기 '는 t는 (내 추론도 맞습니까?) 전자의 경우에 발생

요약 : 그들이에서 쿼리 실행시에 있었던 같은 결과 나는 그 2 개 000 000의 모든 레코드를 보낼 분할 된 방식으로. 이 문제를 너무 과소 평가하고 있습니까? 새로운 기록을 건너 뛰는 것은 업데이트 작업의 향후 처형의 경우에 그렇게 문제가되지 않을 수 있습니까? 아니면 RepositoryItemReader에 관한 내 추론이 올바르지 않습니까?

답변

0

커서를 장시간 열어 두는 것이 항상 이상한 것은 아닙니다. 사용중인 DB에 따라 최적화되지 않을 수도 있습니다. 즉, 일부 DB는 fetchSize를 따르지 않으며 요청 될 때마다 하나씩 결과를 검색합니다.

RepositoryItemReader 또는 PagingItemReader 구현 중 하나를 선택했습니다.

귀하가 걱정 하시거나 새로운 기록을 생략하고 싶지 않다면 다음과 같지 않습니다.

새 레코드를 생략하려면 where 절에 술어를 추가하여 특정 ID 또는 타임 스탬프 필드를 전달할 수 있어야합니다. 이들 중 어느 것도 사용할 수없는 경우 작업 전 (예 : 청취자)에서 실행 한 카운트 쿼리를 기반으로 리더에서 maxItemCount()를 설정할 수 있습니다.