-
Batch 정리[공부] 프로그래밍/Spring・Spring Boot (JAVA) 2025. 4. 12. 15:40
배치
일정한 시점에 자동으로 여러 작업을 한 번에 처리하는 방식이다. 특히 사람이 일일이 하지 않고 컴퓨터가 정해진 시간에 알아서 하는 작업을 말한다.
▷ 배치 예시
💼 회사에서의 급여 계산:
회사는 매일 급여를 계산하지 않고 한 달에 한 번, 모든 직원의 근무시간, 수당 등을 모아서 한 번에 급여를 계산한다. 이것을 "배치 작업"으로 자동화할 수 있다. (예: 매달 말일 밤 12시에 자동으로 급여 계산 실행)
📊 통계 데이터 모으기:
웹사이트 방문자 수나 매출 데이터를 매일 밤에 한 번 모아서 하루 치 통계 정리하는 경우도 해당한다.
▷ 배치를 사용하는 이유
・효율성 : 한꺼번에 처리함으로 리소스를 아낄 수 있다.
・자동화 가능 : 사람이 일일이 하지 않아도 된다.
・야간 처리 가능: 사용자 없는 시간에 돌릴 수 있어서 시스템에 부담이 적다.
Spring Batch
Spring Batch는 대량의 데이터를 일괄 처리(batch processing) 하기 위한 프레임워크이다. 아래에 간단한 예시를 통해 전체적인 구조와 흐름을 파악할 수 있다.
▷ 시나리오
간단한 CSV 파일에서 이름을 읽고, 모두 대문자로 변환해서 출력하는 배치 작업
▷ 기본 구조
Spring Batch는 크게 3단계로 구성된다.
단계 역활 Reader 데이터를 읽는다. (예: CSV 파일, DB 등) Processor 데이터를 가공한다. (예: 이름을 대문자로 바꾸기) Writer 데이터를 출력하거나 저장한다. (예: DB, 파일 등)
▷ 예제 코드
① ItemReader – 이름을 파일에서 읽기
@Bean public FlatFileItemReader<String> reader() { return new FlatFileItemReaderBuilder<String>() .name("nameItemReader") .resource(new ClassPathResource("names.csv")) .lineMapper((line, lineNumber) -> line) .build(); }
・.name("nameItemReader") : 리더에 이름을 부여 (디버깅이나 모니터링 용도)
・.resource(...) : 읽을 파일의 경로 지정
・(resources/names.csv).lineMapper(...) : 한 줄(line)을 어떻게 처리할지 정의, 여기선 그대로 String으로 반환
=> names.csv에 Alice라는 줄이 있으면, 이 리더는 "Alice"라는 String을 반환함
② ItemProcessor – 이름을 대문자로 바꾸기
@Bean public ItemProcessor<String, String> processor() { return name -> name.toUpperCase(); }
・ItemProcessor<Input, Output> : 입력과 출력 타입 지정
・(String → String)name -> name.toUpperCase() : 람다식으로 이름을 전부 대문자로 바꿈
=> "Alice"→"ALICE"
③ ItemWriter – 결과 출력 or 저장
@Bean public ItemWriter<String> writer() { return items -> { for (String item : items) { System.out.println(">> " + item); } }; }
・ItemWriter<List<String>> : 데이터를 처리 후 저장하거나 출력하는 단계
・for (String item : items) : 처리된 데이터를 하나씩 꺼냄
・System.out.println(...) : 콘솔에 출력함
=> ALICE
④ Step과 Job 구성
@Bean public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) { return new StepBuilder("step1", jobRepository) .<String, String>chunk(5, transactionManager) .reader(reader()) .processor(processor()) .writer(writer()) .build(); } @Bean public Job job(JobRepository jobRepository, JobLauncher jobLauncher) { return new JobBuilder("job", jobRepository) .start(step1(jobRepository, transactionManager())) .build(); }
・StepBuilder("step1", jobRepository) : step 이름과 job 저장소 설정
・<String, String> : reader → processor → writer 모두 String 처리
・chunk(5, transactionManager) : 5개씩 처리하고 커밋함
・.reader(), .processor(), .writer() : 각각의 구성요소 연결
・JobBuilder("job", jobRepository) : job 이름 설정
・.start(step1(...)) : 첫 번째 step 지정.build() : job 생성
프로젝트 예제
① Config
package test.test1.batch01.config; import … @Configuration @RequiredArgsConstructor public class Batch01Config { private final Batch01Service Batch01Service; @Bean(name = Batch01Constant.JOB_Batch01) public Job Batch01Job(FcJobNotificationListener fcJobNotificationListener, Step Batch01Step, JobRepository jobRepository) { return new JobBuilder(Batch01Constant.JOB_Batch01, jobRepository) .incrementer(new RunIdIncrementer()) .listener(fcJobNotificationListener) .flow(Batch01Step) .end() .build(); } @Bean public Step Batch01Step(FcStepLoggingListener fcStepLoggingListener, Tasklet Batch01Tasklet, JobRepository jobRepository, PlatformTransactionManager transactionManager) { return new StepBuilder(Batch01Constant.STEP_Batch01, jobRepository) .tasklet(Batch01Tasklet, transactionManager) .listener(fcStepLoggingListener) .build(); } @Bean @StepScope public Tasklet Batch01Tasklet() { MethodInvokingTaskletAdapter tasklet = new MethodInvokingTaskletAdapter(); tasklet.setTargetObject(Batch01Service); tasklet.setTargetMethod(Batch01Constant.TEST); return tasklet; } }
▷ 전체 구성 요약
이 클래스는 Spring Batch에서 Job → Step → Tasklet → Service 메서드 호출 구조로 배치 처리를 정의하는 것이다.
・Job: 배치 전체 흐름 정의
・Step: 작업 단위
・Tasklet: 단일 작업 수행 (보통 1개의 메서드 호출)
・Service: 실제 로직을 구현하는 클래스
▷ 보충 설명
・@Configuration: 이 클래스가 Spring 설정 파일임을 의미한다.
・@RequiredArgsConstructor: final로 선언된 필드를 자동으로 생성자 주입해준다. → DI(의존성 주입) 편리하게 가능
📌 생성자 주입이란?
클래스에서 필요한 의존성 객체(다른 클래스의 객체)를 생성자를 통해 전달받는 걸 말한다.
예를 들어 아래처럼 어떤 클래스가 있을 때:
public class MyService { private final MemberRepository memberRepository; public MyService(MemberRepository memberRepository) { this.memberRepository = memberRepository; } }
이 클래스는 MemberRepository라는 의존성 객체가 꼭 필요해서 생성자를 통해 전달받아야만 동작할 수 있다.
그런데 이걸 매번 쓰기 귀찮기 때문에
그래서 Lombok의 @RequiredArgsConstructor를 쓰면@RequiredArgsConstructor public class MyService { private final MemberRepository memberRepository; }
final로 선언된 필드에 대해서 자동으로 생성자를 만들준다.
・FcStepLoggingListener : Step 실행 전/후에 로그 출력이나 사용자 정의 로직을 수행하기 위한 리스너
・JobRepository : 배치 처리의 상태 관리와 기록을 담당하며 Job/Step 실행 정보, 실행 결과, 파라미터 등을 DB에 저장한다.
・PlatformTransactionManager : 트랜잭션을 관리하는 역할을 하며 (예: 커밋, 롤백) Tasklet 안에서 예외가 발생하면 롤백이 되고, 문제 없으면 커밋된다.
▷ Jop・RunIdIncrementer(): 실행할 때마다 runId를 자동 증가시켜 JobInstance를 새로 만들게 한다.
▷ Step
・listener(...): Job 실행 전후에 로그나 알림을 수행할 수 있는 리스너
・flow(...): 실행할 Step 지정
・build(): Job 객체 완성
・tasklet(...): Tasklet 방식으로 처리 (한 번의 실행으로 끝나는 단순 처리)
・listener(...): Step 전후 로그를 찍을 수 있는 리스너▷ Tasklet
・@StepScope: 이 Tasklet은 Step 실행 시점에 생성됩니다 (지연 생성)
・MethodInvokingTaskletAdapter: 특정 메서드 호출만 할 때 사용하는 간단한 Tasklet 구현체
② Constant
package test.test1.batch01.constant; import ... public final class Batch01Constant { public static final String TEST = "test01"; }
③ Service
package test.test1.batch01.service; import ... public interface Batch01Service { void test01() throws Exception; }
package test.test1.batch01.service.impl; import ... @Service @RequiredArgsConstructor public class Batch01ServiceImpl implements Batch01Service { private final TestRepository testRepository; @Override @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) public void test01() throws Exception { // 비즈니스 로직 예시 List<Test01ResultDb> searchResultList = testRepository.selectTest01(); } }
▷ @Transactional
・propagation = Propagation.REQUIRES_NEW :
이 메서드를 호출한 쪽에서 이미 트랜잭션이 있어도 무시하고, 새로운 트랜잭션을 시작한다.
사용 시점: 예를 들어 배치 처리 중 한 건 실패하더라도 전체가 영향을 받지 않게 하고 싶을 때
・rollbackFor = Exception.class
기본적으로 @Transactional은 RuntimeException이나 Error가 발생할 때만 롤백한다. 그런데 여기서는 모든 Exception이 발생해도 롤백되게끔 설정한 것이다.
2024.04.16 - [[공부] 프로그래밍/Spring Boot (JAVA)] - Spring Batch 구현 - 1
Spring Batch 구현 - 1
♧ 전체 코드 : https://github.com/woodisco/pass-batch GitHub - woodisco/pass-batchContribute to woodisco/pass-batch development by creating an account on GitHub.github.com 프로젝트 생성 및 샘플 코드 작성Spring bootGradleSpring BatchMySQL
woodisco.tistory.com
2024.04.24 - [[공부] 프로그래밍/Spring Boot (JAVA)] - Spring Batch 구현 - 2
Spring Batch 구현 - 2
♧ 전체 코드 : https://github.com/woodisco/pass-batch GitHub - woodisco/pass-batchContribute to woodisco/pass-batch development by creating an account on GitHub.github.com JPA 연동① repository 작성repository/bookingrepository/notificationreposit
woodisco.tistory.com
2024.04.24 - [[공부] 프로그래밍/Spring Boot (JAVA)] - Spring Batch 구현 - 3
Spring Batch 구현 - 3
♧ 전체 코드 : https://github.com/woodisco/pass-batch GitHub - woodisco/pass-batchContribute to woodisco/pass-batch development by creating an account on GitHub.github.com 이용권 일괄 지급 배치① AddPassesJopConfig 작성package com.fastcamp
woodisco.tistory.com
2024.04.25 - [[공부] 프로그래밍/Spring Boot (JAVA)] - Spring Batch 구현 - 4
Spring Batch 구현 - 4
♧ 전체 코드 : https://github.com/woodisco/pass-batch GitHub - woodisco/pass-batchContribute to woodisco/pass-batch development by creating an account on GitHub.github.com 수업 전 알람 배치① SendNotificationBeforeClassJobConfig 작성@Beanpub
woodisco.tistory.com
2024.05.08 - [[공부] 프로그래밍/Spring Boot (JAVA)] - Spring Batch 구현 - 5
Spring Batch 구현 - 5
♧ 전체 코드 : https://github.com/woodisco/pass-batch GitHub - woodisco/pass-batchContribute to woodisco/pass-batch development by creating an account on GitHub.github.com 수업 종료후, 이용권 차감 배치① UsePassesJobConfig 작성@Configur
woodisco.tistory.com
2024.05.09 - [[공부] 프로그래밍/Spring Boot (JAVA)] - Spring Batch 구현 - 6
Spring Batch 구현 - 6
♧ 전체 코드 : https://github.com/woodisco/pass-batch GitHub - woodisco/pass-batchContribute to woodisco/pass-batch development by creating an account on GitHub.github.com 통계 데이터 생성 배치① StatisticsRepository 작성② StatisticsEnti
woodisco.tistory.com
2024.05.14 - [[공부] 프로그래밍/Spring Boot (JAVA)] - Spring Batch 구현 - 7
Spring Batch 구현 - 7
♧ 전체 코드 : https://github.com/woodisco/pass-batch GitHub - woodisco/pass-batchContribute to woodisco/pass-batch development by creating an account on GitHub.github.com REST API로 Job 실행시키기① JobLauncherRequest 작성@Getter@Setter@ToSt
woodisco.tistory.com
'[공부] 프로그래밍 > Spring・Spring Boot (JAVA)' 카테고리의 다른 글
API 정리 (0) 2025.04.13 Logback 구현 - 2 (0) 2024.05.23 Logback 구현 - 1 (0) 2024.05.22 Feign Client 구현 - 4 (0) 2024.05.22 Feign Client 구현 - 3 (0) 2024.05.22