[파일처리] 5. FlatFileItemWriter와 커밋, 롤백, 파일 옵션

y001·2026년 3월 8일

Spring Batch Guide

목록 보기
15/19
post-thumbnail

1. shouldDeleteIfExists

FlatFileItemWriter는 기본적으로 실행 시 동일한 이름의 파일이 존재하면 해당 파일을 삭제하고 새 파일을 생성한다. 이 동작은 shouldDeleteIfExists 옵션으로 제어할 수 있다.

new FlatFileItemWriterBuilder<ErrorLog>()
        .name("errorLogWriter")
        .resource(new FileSystemResource("error_logs.csv"))
        .shouldDeleteIfExists(true)
        .build();

이 옵션의 기본값은 true이다. 따라서 동일한 파일이 존재하더라도 기존 파일은 삭제되고 새로운 실행 결과로 파일이 다시 생성된다. 대부분의 배치 작업에서는 매 실행마다 새로운 결과 파일을 만드는 것이 일반적이기 때문에 기본 설정 그대로 사용하는 경우가 많다.

반대로 기존 파일 뒤에 데이터를 이어서 기록해야 하는 상황도 있다. 예를 들어 로그 누적 파일이나 장기간 데이터를 쌓아야 하는 경우가 그렇다. 이런 경우에는 append(true) 옵션을 사용할 수 있다. 이 설정을 사용하면 기존 파일은 삭제되지 않고 새로운 데이터가 파일 끝에 추가된다.

new FlatFileItemWriterBuilder<ErrorLog>()
        .name("errorLogWriter")
        .resource(new FileSystemResource("error_logs.csv"))
        .append(true)
        .build();

2. shouldDeleteIfEmpty, 빈 파일 처리

배치 작업이 실행되었지만 실제로 처리된 데이터가 없는 경우도 있다. 예를 들어 Reader 단계에서 데이터가 하나도 읽히지 않았다면 Writer는 아무 내용도 기록하지 않게 된다. 이 경우 실행 결과로 빈 파일이 생성될 수도 있다.

new FlatFileItemWriterBuilder<ErrorLog>()
        .name("errorLogWriter")
        .resource(new FileSystemResource("error_logs.csv"))
        .shouldDeleteIfEmpty(true)
        .build();

FlatFileItemWriter는 이러한 상황을 제어하기 위해 shouldDeleteIfEmpty 옵션을 제공한다. 이 옵션이 활성화되면 Writer는 Step이 종료된 뒤 실제 데이터가 하나도 기록되지 않았을 경우 생성된 파일을 삭제한다. 즉 실행 결과가 없는 배치라면 파일 자체가 남지 않는다.

다만 append(true) 옵션과 함께 사용할 때는 주의해야 한다. 현재 실행에서 데이터가 없더라도 기존 파일이 존재한다면 해당 파일이 삭제될 수 있기 때문이다. 따라서 누적 로그 파일을 유지해야 하는 환경에서는 이 옵션을 신중하게 설정해야 한다.

3. transactional, 파일 기록과 트랜잭션

파일 시스템은 데이터베이스와 달리 완전한 트랜잭션 롤백을 지원하지 않는다. 파일에 기록된 데이터는 되돌리기 어렵기 때문에 배치 처리에서는 파일 기록 시점이 중요하다. FlatFileItemWriter는 문자열을 생성하자마자 파일에 기록하지 않는다. 대신 생성된 문자열을 내부 버퍼에 보관해 두었다가 chunk 처리가 정상적으로 commit되는 시점에 한 번에 파일에 기록한다. 따라서 chunk 처리 도중 예외가 발생하면 버퍼에 있던 데이터는 폐기되고 파일에는 아무 내용도 남지 않는다.

이 동작은 transactional 옵션으로 제어할 수 있다. 기본값은 true이며 대부분의 경우 이 값을 그대로 사용하는 것이 안전하다. 이 옵션이 활성화된 상태에서는 commit이 완료되기 전까지 실제 파일에는 데이터가 기록되지 않는다.

new FlatFileItemWriterBuilder<ErrorLog>()
        .name("errorLogWriter")
        .resource(new FileSystemResource("error_logs.csv"))
        .transactional(true)
        .build();

4. forceSync, 파일 동기화

new FlatFileItemWriterBuilder<ErrorLog>()
        .name("errorLogWriter")
        .resource(new FileSystemResource("error_logs.csv"))
        .forceSync(true)
        .build();

이 옵션을 활성화하면 파일이 기록될 때 운영체제의 파일 버퍼가 디스크에 즉시 동기화된다. 즉 데이터가 메모리 캐시에만 남아 있는 상태가 아니라 실제 디스크에 저장된다. 다만 이 옵션은 디스크 I/O 비용을 증가시키기 때문에 일반적인 배치 작업에서는 사용하지 않는 경우도 많다. 데이터 손실 가능성을 최소화해야 하는 환경에서만 사용하는 것이 일반적이다.

0개의 댓글