[SPRING] Spring 배치 : 집계 된 리더 / 작성기 문제
SPRINGSpring 배치 : 집계 된 리더 / 작성기 문제
Spring 배치를 사용하고 집계 된 판독기 (배치 파일, 여러 레코드를 기록하는 동안 하나의 레코드로 처리해야 함)를 구현하려고합니다. 내 독자를위한 코드 스 니펫은 다음과 같습니다.
public class AggregatePeekableReader implements ItemReader<List<T>>, ItemStream {
private SingleItemPeekableItemReader<T> reader;
private boolean process(T currentRecord , InvoiceLineItemsHolder holder) throws UnexpectedInputException, ParseException, Exception {
next = peekNextInvoiceRecord();
// finish processing if we hit the end of file
if (currentRecord == null ) {
LOG.info("Exhausted ItemReader ( END OF FILE)");
holder.exhausted = true;
return false;
}
if ( currentRecord.hasSameInvoiceNumberAndVendorNumber(next)){
LOG.info("Found new line item to current invocie record");
holder.records.add(currentRecord);
currentRecord = null;
return true;
}else{
holder.records.add(currentRecord);
return false;
}
}
private T getNextInvoiceRecord () {
T record=null;
try {
record=reader.read();
} catch (UnexpectedInputException e) {
ALERT.error(LogMessageFormatter.format(Severity.HIGH,
BATCH_FILE_READ_EXCEPTION, e), e);
throw e;
} catch (ParseException e) {
ALERT.error(LogMessageFormatter.format(Severity.HIGH,
BATCH_FILE_READ_EXCEPTION, e), e);
throw e;
} catch (Exception e) {
ALERT.error(LogMessageFormatter.format(Severity.HIGH,
BATCH_FILE_READ_EXCEPTION, e), e);
}
return record;
}
private T peekNextInvoiceRecord() {
T next=null;
try {
next=reader.peek();
} catch (UnexpectedInputException e) {
ALERT.error(LogMessageFormatter.format(Severity.HIGH,
BATCH_FILE_READ_EXCEPTION, e), e);
throw e;
} catch (ParseException e) {
ALERT.error(LogMessageFormatter.format(Severity.HIGH,
BATCH_FILE_READ_EXCEPTION, e), e);
throw e;
} catch (Exception e) {
ALERT.error(LogMessageFormatter.format(Severity.HIGH,
BATCH_FILE_READ_EXCEPTION, e), e);
}
return next;
}
public void close () {
reader.close();
}
public SingleItemPeekableItemReader<T> getReader() {
return reader;
}
public void setReader(SingleItemPeekableItemReader<T> reader) {
this.reader = reader;
}
private class InvoiceLineItemsHolder {
List<T> records = new ArrayList<T>();
boolean exhausted = false;
}
@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
//
reader.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
// TODO
}
@Override
public List<T> read() throws Exception, UnexpectedInputException, ParseException,
NonTransientResourceException {
CLASS holder = new SOMECLASS()
synchronized (this) {
while (process(getNextInvoiceRecord(), holder)) {
continue;
}
if (!holder.exhausted) {
return holder.records;
} else {
//When you hit the end of the file,close the reader.
close();
return null;
}
}
}
}
위의 내용은 엿보기 가능한 독자 구현을위한 작업 예제입니다. 다음 줄을 엿볼 수 있습니다. (그것을 읽지 않는다), 논리적 인 라인 끝에 도달했는지를 결정한다 (몇 번 여러 행이 단일 트랜잭션을 구성 할 수 있음)
해결법
-
==============================
1.독자를 위해 ItemStream 인터페이스를 구현해야합니다. 이렇게하면 스프링 배치 (Spring Batch)에 힌트가 주어지며 독자는 스트림을 열고 닫는 데 몇 가지 작업이 필요합니다.
독자를 위해 ItemStream 인터페이스를 구현해야합니다. 이렇게하면 스프링 배치 (Spring Batch)에 힌트가 주어지며 독자는 스트림을 열고 닫는 데 몇 가지 작업이 필요합니다.
public class InvoiceLineItemAggregatePeekableReader extends AbstractItemStreamItemReader<List<SAPInvoicePaymentRecord>> { @Override public void close() { ... } }
단계 실행 중 오류가 발생해도 스트림은 닫힙니다. 더 많은 예제를 보려면 Spring Batch 자체의 클래스 (예 : FlatFileItemReader)를 확인하십시오.
-
==============================
2.파일을 복사하고 나중에 삭제할 수 있도록 이전 파일에서 File.deleteOnExit ()을 사용하거나 추가 단계에서 이전 파일을 삭제할 수 있습니다 (예 : 비즈니스 단계에 예외가있는 경우에만 deleteTaskletStep을 호출하는 간단한 태스크 릿 및 플로우
파일을 복사하고 나중에 삭제할 수 있도록 이전 파일에서 File.deleteOnExit ()을 사용하거나 추가 단계에서 이전 파일을 삭제할 수 있습니다 (예 : 비즈니스 단계에 예외가있는 경우에만 deleteTaskletStep을 호출하는 간단한 태스크 릿 및 플로우
from https://stackoverflow.com/questions/8303106/spring-batch-aggregated-reader-writer-issue by cc-by-sa and MIT license