Chunk-Oriented Processing
chunk는 데이터를 일정 크기로 나누어 처리하는 방식으로 chunk를 기준으로 트랜잭션이 관리된다.
데이터를 Read(ItemReader) → Processing(ItemProcessor) → Write(ItemWriter) 단계를 기준으로 나누어 처리한다.
주로 데이터 작업을 수행하는 경우 효과적이다.
@Configuration
class ChunkBatchConfig(
private val jobRepository: JobRepository, private val platformTransactionManager: PlatformTransactionManager,
private val domainRepository: DomainRepository
) {
@Bean
fun chunkJob(): Job {
return JobBuilder("chunkJob", jobRepository).start(chunkStep()).build()
}
@Bean
fun chunkStep(): Step {
return StepBuilder("chunkStep", jobRepository).chunk<Domain, Domain>(1000, platformTransactionManager)
.reader(chunkReader())
.writer(chunkWriter())
.build()
}
@Bean
fun chunkReader(): ItemReader<Domain> {
val data = listOf(Domain(name = "Domain1"), Domain(name = "Domain2"))
val iterator = data.iterator()
return ItemReader {
if (iterator.hasNext()) {
iterator.next()
} else {
null
}
}
}
@Bean
fun chunkWriter(): ItemWriter<Domain> {
return ItemWriter { items ->
domainRepository.saveAll(items)
}
}
}
@SpringBatchTest
@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestPropertySource(properties = ["spring.batch.job.enabled=false"])
class ChunkBatchConfigTest(
@Autowired private val jobLauncherTestUtils: JobLauncherTestUtils,
@Autowired private val chunkJob: Job,
) {
@Test
fun `chunkJob test`() {
// given
jobLauncherTestUtils.job = chunkJob
// when
val jobExecution: JobExecution = jobLauncherTestUtils.launchJob()
// then
assertEquals(BatchStatus.COMPLETED, jobExecution.status)
}
}
Tasklet-Oriented Processing
Tasklet은 단일 작업을 수행하는 방식으로 하나의 작업을 수행한 뒤 종료된다.
chunk가 데이터 처리에 적합한 반면, 작업 단위의 논리적 분리에 적합하다.
복잡하지 않은 작업(ex: 파일 삭제, 데이터 초기화)에서 주로 사용되며 실패 시 전체 작업이 다시 실행된다.
@Configuration
class TaskletBatchConfig(
private val jobRepository: JobRepository,
private val platformTransactionManager: PlatformTransactionManager,
private val domainRepository: DomainRepository
) {
@Bean
fun taskletJob(): Job {
return JobBuilder("taskletJob", jobRepository).start(taskletStep()).build()
}
@Bean
fun taskletStep(): Step {
return StepBuilder("taskletStep", jobRepository)
.tasklet(dataProcessingTasklet(), platformTransactionManager)
.build()
}
@Bean
fun dataProcessingTasklet(): Tasklet {
return Tasklet { _, _ ->
val data = listOf(Domain(name = "Domain1"), Domain(name = "Domain2"))
domainRepository.saveAll(data)
RepeatStatus.FINISHED
}
}
}
@SpringBatchTest
@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestPropertySource(properties = ["spring.batch.job.enabled=false"])
class TaskletBatchConfigTest(
@Autowired private val jobLauncherTestUtils: JobLauncherTestUtils,
@Autowired private val taskletJob: Job,
) {
@Test
fun `taskletJob test`() {
// given
jobLauncherTestUtils.job = taskletJob
// when
val jobExecution: JobExecution = jobLauncherTestUtils.launchJob()
// then
assertEquals(BatchStatus.COMPLETED, jobExecution.status)
}
}
비교
특징 | Tasklet-Oriented Processing | Chunk-Oriented Processing |
---|---|---|
처리 단위 | 단일 작업(Task) 중심 처리 | 데이터를 일정 크기(Chunk)로 나누어 처리 |
적합한 작업 | 파일 삭제, 데이터 초기화 등 단순하고 논리적 작업 분리에 적합 | 대량의 데이터를 읽고 처리한 뒤 저장하는 작업에 적합 |
구성 요소 | Tasklet 구현체 |
ItemReader , ItemProcessor , ItemWriter 구성 |
트랜잭션 관리 단위 | 전체 작업 단위에서 트랜잭션 관리 | Chunk 단위로 트랜잭션 관리 |
병렬 처리 | 기본적으로 병렬 처리에 적합하지 않음 | 병렬 처리 및 대량 데이터 처리에 유리 |
작업 흐름 | 하나의 작업을 정의하고 끝난 뒤 종료 | 데이터를 읽고, 처리하고, 쓰기 단계를 반복 |
실패 처리 | 실패 시 전체 작업을 다시 실행 | 실패 시 Chunk 단위로 재시도 가능 |
복잡성 | 간단한 작업에 적합 (코드 간결) | 데이터 흐름이 분리되어 복잡한 작업에 적합 (구조화된 데이터 처리) |
사용 사례 | 파일 삭제, 데이터 초기화, 메타데이터 업데이트 | 대량 데이터 처리, 데이터 마이그레이션, 데이터베이스와 파일 간 데이터 이동 |
코드 예제 | 단일 Tasklet 으로 작업 정의 |
ItemReader , ItemProcessor , ItemWriter 로 작업 분리 |
'IT > Spring' 카테고리의 다른 글
HikariCP 데드락 이슈 (3) | 2024.11.14 |
---|---|
Spring Batch Writer 성능 비교 (0) | 2024.11.13 |
Spring Boot 3.2 변경점 (3) | 2023.11.24 |
스프링의 트랜잭션 (0) | 2023.10.12 |
Spring AOP 분석 (0) | 2023.10.10 |
댓글