복붙노트

[SPRING] Spring 배치 : 집계 된 리더 / 작성기 문제

SPRING

Spring 배치 : 집계 된 리더 / 작성기 문제

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. ==============================

    1.독자를 위해 ItemStream 인터페이스를 구현해야합니다. 이렇게하면 스프링 배치 (Spring Batch)에 힌트가 주어지며 독자는 스트림을 열고 닫는 데 몇 가지 작업이 필요합니다.

    독자를 위해 ItemStream 인터페이스를 구현해야합니다. 이렇게하면 스프링 배치 (Spring Batch)에 힌트가 주어지며 독자는 스트림을 열고 닫는 데 몇 가지 작업이 필요합니다.

    public class InvoiceLineItemAggregatePeekableReader extends AbstractItemStreamItemReader<List<SAPInvoicePaymentRecord>> {
    
        @Override
        public void close() {
        ...
        }
    }
    

    단계 실행 중 오류가 발생해도 스트림은 닫힙니다. 더 많은 예제를 보려면 Spring Batch 자체의 클래스 (예 : FlatFileItemReader)를 확인하십시오.

  2. ==============================

    2.파일을 복사하고 나중에 삭제할 수 있도록 이전 파일에서 File.deleteOnExit ()을 사용하거나 추가 단계에서 이전 파일을 삭제할 수 있습니다 (예 : 비즈니스 단계에 예외가있는 경우에만 deleteTaskletStep을 호출하는 간단한 태스크 릿 및 플로우

    파일을 복사하고 나중에 삭제할 수 있도록 이전 파일에서 File.deleteOnExit ()을 사용하거나 추가 단계에서 이전 파일을 삭제할 수 있습니다 (예 : 비즈니스 단계에 예외가있는 경우에만 deleteTaskletStep을 호출하는 간단한 태스크 릿 및 플로우

  3. from https://stackoverflow.com/questions/8303106/spring-batch-aggregated-reader-writer-issue by cc-by-sa and MIT license