๋ฐฐ์น(Batch)์์ ์ ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์๋๋ผ, ์ผ๊ด์ ์ผ๋ก ๋ชจ์์ ํ๋ฒ์ ์ฒ๋ฆฌํ๋ ์์ ์ ์๋ฏธํฉ๋๋ค.
์๋ฅผ ๋ค๋ฉด ์ํ์ ์ ์ฐ ์์ ์ ๊ฒฝ์ฐ ๋ฐฐ์น ์์ ์ ํตํด ์ผ๊ด์ฒ๋ฆฌ๋ฅผ ์ํํ๊ฒ ๋๋ฉฐ ์ฌ์ฉ์๊ฐ์ ๋น ๋ฅธ ์๋ต์ด ํ์ํ์ง ์์ ์๋น์ค์ ์ ์ฉํ ์ ์์ต๋๋ค.
๋ ๋ค๋ฅธ ์๋ก๋ ์ผํ๋ชฐ ๊ฐ์ VIP์์คํ ์ด ์๋ ๊ณณ์์ ํ๋ฌ ๋์ ์ด์ฉ๋์ ํ์ธํ ๋ค ๋ถ์ฌํ๋ ์์คํ ์๋ ํ์ฉํ ์ ์์ต๋๋ค.
Spring Batch๋ ๋๋์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ๊ฒฝ๋ํ๋ ํ๋ ์์ํฌ๋ก, ๋ฐ๋ณต์ ์ธ ์์ ์ ์ํํ๋ ์ผ๊ด ์ฒ๋ฆฌ (Batch Processing) ์์ ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ ์ฃผ๊ธฐ์ ์ธ ์ ๋ฌด ์ฒ๋ฆฌ ๋ฑ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ณ , ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ์ ํฉํ ๋ถ์ฐ ๋ฐฉ์์ ์ฒ๋ฆฌ๋ฅผ ์ง์ํฉ๋๋ค.
Spring Batch vs Quartz? Scheduler?
Spring Batch๋ Batch Job์ ๊ด๋ฆฌํ์ง๋ง Job์ ๊ตฌ๋ํ๊ฑฐ๋ ์คํ์ํค๋ ๊ธฐ๋ฅ์ ์ง์ํ๊ณ ์์ง ์์ต๋๋ค. Spring์์ Batch Job์ ์คํ์ํค๊ธฐ ์ํด์๋ Quartz, Scheduler, Jenkins๋ฑ ์ ์ฉ Scheduler๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Spring Batch๋ ๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ผ๋ฉฐ, ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
Job
Job์ ๋ฐฐ์น์ฒ๋ฆฌ ๊ณผ์ ์ ํ๋์ ๋จ์๋ก ๋ง๋ค์ด ๋์ ๊ฐ์ฒด์ ๋๋ค. ๋ํ ๋ฐฐ์น์ฒ๋ฆฌ ๊ณผ์ ์ ์์ด ์ ์ฒด ์ต์๋จ์ ์์นํ๊ณ ์์ต๋๋ค.
JobInstance
JobInstance๋ Job์ ์คํ ๋จ์๋ฅผ ๋ํ๋ ๋๋ค. Job์ ์คํ์ํค๊ฒ ๋๋ฉด ํ๋์ JobInstance๊ฐ ์์ฑ๋๊ฒ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด 10์ 1์ผ ์คํ, 10์ 2์ผ ์คํ์ ํ๊ฒ ๋๋ฉด ๊ฐ๊ฐ์ JobInstance๊ฐ ์์ฑ๋๋ฉฐ 1์ 1์ผ ์คํํ JobInstance๊ฐ ์คํจํ์ฌ ๋ค์ ์คํ์ ์ํค๋๋ผ๋ ์ด JobInstance๋ 1์ 1์ผ์ ๋ํ ๋ฐ์ดํฐ๋ง ์ฒ๋ฆฌํ๊ฒ ๋ฉ๋๋ค.
JobParmeters
JobParmeters๋ JobInstance๋ฅผ ๊ตฌ๋ณํ๊ธฐ ์ํ ๊ฐ์ฒด์ ๋๋ค. JobParmeters๋ JobInstance ๊ตฌ๋ณ์ธ์๋ ๊ฐ๋ฐ์ JobInstance์ ์ ๋ฌ๋๋ ๋งค๊ฐ๋ณ์ ์ญํ ๋ ํ๊ณ ์์ต๋๋ค.
๋ํ JobParmeters๋ String, Double, Long, Date 4๊ฐ์ง ํ์๋ง์ ์ง์ํ๊ณ ์์ต๋๋ค.
JobExecution
JobExecution์ JobInstance์ ๋ํ ์คํ ์๋์ ๋ํ ๊ฐ์ฒด์ ๋๋ค. 1์ 1์ผ์ ์คํํ JobInstance๊ฐ ์คํจํ์ฌ ์ฌ์คํ์ ํ์ฌ๋ ๋์ผํ JobInstance๋ฅผ ์คํ์ํค์ง๋ง ์ด 2๋ฒ์ ์คํ์ ๋ํ JobExecution์ ๊ฐ๋ณ๋ก ์๊ธฐ๊ฒ ๋ฉ๋๋ค. JobExecution์ ์ด๋ฌํ JobInstance ์คํ์ ๋ํ ์ํ, ์์์๊ฐ, ์ข ๋ฃ์๊ฐ, ์์ฑ์๊ฐ ๋ฑ์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์์ต๋๋ค.
Step
Step์ Job์ ๋ฐฐ์น์ฒ๋ฆฌ๋ฅผ ์ ์ํ๊ณ ์์ฐจ์ ์ธ ๋จ๊ณ๋ฅผ ์บก์ํํฉ๋๋ค. Job์ ์ต์ํ 1๊ฐ ์ด์์ Step์ ๊ฐ์ ธ์ผ ํ๋ฉฐ Job์ ์ค์ ์ผ๊ด ์ฒ๋ฆฌ๋ฅผ ์ ์ดํ๋ ๋ชจ๋ ์ ๋ณด๊ฐ ๋ค์ด์์์ต๋๋ค.
StepExceution
StepExceution์ JobExceution๊ณผ ๋์ผํ๊ฒ Step ์คํ ์๋์ ๋ํ ๊ฐ์ฒด๋ฅผ ๋ํ๋ ๋๋ค. ํ์ง๋ง Job์ด ์ฌ๋ฌ๊ฐ์ Step์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ ๊ฒฝ์ฐ ์ด์ ๋จ๊ณ์ Step์ด ์คํจํ๊ฒ ๋๋ฉด ๋ค์ ๋จ๊ณ๊ฐ ์คํ๋์ง ์์์ผ๋ก ์คํจ ์ดํ StepExecution์ ์์ฑ๋์ง ์์ต๋๋ค. StepExecution ๋ํ JobExecution๊ณผ ๋์ผํ๊ฒ ์ค์ ์์์ด ๋ ๋๋ง ์์ฑ๋ฉ๋๋ค. StepExecution์๋ JobExecuton์ ์ ์ฅ๋๋ ์ ๋ณด ์ธ์ read ์, write ์, commit ์, skip ์ ๋ฑ์ ์ ๋ณด๋ค๋ ์ ์ฅ์ด ๋ฉ๋๋ค.
ExecutionContext
ExecutionContext๋ Job์์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์๋ ๋ฐ์ดํฐ ์ ์ฅ์์ ๋๋ค. Spring Batch์์ ์ ๊ณตํ๋ ExecutionContext๋ JobExecutionContext, StepExecutionContext 2๊ฐ์ง ์ข ๋ฅ๊ฐ ์์ผ๋ ์ด ๋๊ฐ์ง๋ ์ง์ ๋๋ ๋ฒ์๊ฐ ๋ค๋ฆ ๋๋ค. JobExecutionContext์ ๊ฒฝ์ฐ Commit ์์ ์ ์ ์ฅ๋๋ ๋ฐ๋ฉด StepExecutionContext๋ ์คํ ์ฌ์ด์ ์ ์ฅ๋๊ฒ ๋ฉ๋๋ค. ExecutionContext๋ฅผ ํตํด Step๊ฐ Data๊ณต์ ๊ฐ ๊ฐ๋ฅํ๋ฉฐ Job์คํจ์ ExecutionContext๋ฅผ ํตํ ๋ง์ง๋ง ์คํ ๊ฐ์ ์ฌ๊ตฌ์ฑ ํ ์ ์์ต๋๋ค.
JobRepository
JobRepository๋ ์์์ ๋งํ ๋ชจ๋ ๋ฐฐ์น ์ฒ๋ฆฌ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ๋งค์ปค๋์ฆ์ ๋๋ค. Job์ด ์คํ๋๊ฒ ๋๋ฉด JobRepository์ JobExecution๊ณผ StepExecution์ ์์ฑํ๊ฒ ๋๋ฉฐ JobRepository์์ Execution ์ ๋ณด๋ค์ ์ ์ฅํ๊ณ ์กฐํํ๋ฉฐ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
JobLauncher
JobLauncher๋ Job๊ณผ JobParameters๋ฅผ ์ฌ์ฉํ์ฌ Job์ ์คํํ๋ ๊ฐ์ฒด์ ๋๋ค.
ItemReader
ItemReader๋ Step์์ Item์ ์ฝ์ด์ค๋ ์ธํฐํ์ด์ค์ ๋๋ค. ItemReader์ ๋ํ ๋ค์ํ ์ธํฐํ์ด์ค๊ฐ ์กด์ฌํ๋ฉฐ ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก Item์ ์ฝ์ด ์ฌ ์ ์์ต๋๋ค.
ItemWriter
ItemWriter๋ ์ฒ๋ฆฌ ๋ Data๋ฅผ Writer ํ ๋ ์ฌ์ฉํฉ๋๋ค. Writer๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฌผ์ ๋ฐ๋ผ Insert๊ฐ ๋ ์๋ Update๊ฐ ๋ ์๋ Queue๋ฅผ ์ฌ์ฉํ๋ค๋ฉด Send๊ฐ ๋ ์๋ ์์ต๋๋ค. Writer๋ํ Read์ ๋์ผํ๊ฒ ๋ค์ํ ์ธํฐํ์ด์ค๊ฐ ์กด์ฌํฉ๋๋ค. Writer๋ ๊ธฐ๋ณธ์ ์ผ๋ก Item์ Chunk๋ก ๋ฌถ์ด ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค.
ItemProcessor
ItemProcessor๋ Reader์์ ์ฝ์ด์จ Item์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ์ญํ ์ ํ๊ณ ์์ต๋๋ค. Processor๋ ๋ฐฐ์น๋ฅผ ์ฒ๋ฆฌํ๋๋ฐ ํ์ ์์๋ ์๋๋ฉฐ Reader, Writer, Processor์ฒ๋ฆฌ๋ฅผ ๋ถ๋ฆฌํ์ฌ ๊ฐ๊ฐ์ ์ญํ ์ ๋ช ํํ๊ฒ ๊ตฌ๋ถํ๊ณ ์์ต๋๋ค.
๊ฐ์ฅ ๋จผ์ Application์ Spring Batch๋ฅผ ์ฌ์ฉํ ๊ฒ ์ด๋ผ๊ณ ์ด๋ ธํ ์ด์ ์ ๋ฌ์์ค๋๋ค.
@EnableBatchProcessing // ํด๋น ์ด๋
ธํ
์ด์
@SpringBootApplication
public class SpringBatchApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBatchApplication.class, args);
}
}
๊ฐ๋จํ๊ฒ Spring Batch์ ์ค์ ํ ์ ์์ต๋๋ค.
์ดํ ์ ๋ MySQL๊ณผ ์ฐ๋์ ํ ๊ฒ ์ด๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด ํ๊ฒฝ ์ค์ ์ ํด์ฃผ์์ต๋๋ค.
spring:
application:
name: spring-batch
datasource:
url: jdbc:mysql://localhost:3307/batch
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 1234
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
sql:
init:
mode: always
sql.init.mode๋ฅผ ์ค์ ํ ์ด์ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ํ ํ
์ด๋ธ์ ๊ตฌ์ฑํ๊ธฐ ์ํด resources-schema.sql์ ํ
์ด๋ธ ๊ด๋ จ SQL๋ฌธ์ ์์ฑํด๋์์ต๋๋ค.

ํด๋น ์คํค๋ง ์ ๋ณด๋ spring-batch-core-5.1.2.jar - org - springframework - batch - core - schema-mysql.sql ์ ์์ต๋๋ค.
ํด๋น ํ ์ด๋ธ์ด ์๋๊ฒฝ์ฐ ์ ์์ ์ผ๋ก ์คํ๋์ง ์์ต๋๋ค.
Spring Batch์์ Job์ ์ฌ๋ฌ๊ฐ์ง Step์ ๋ชจ์์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ, Job์ ์์ฐจ์ ์ธ Step์ ์ํํ๋ฉฐ Batch๋ฅผ ์ํํ๊ฒ ๋ฉ๋๋ค. Step์ Tasklet ์ฒ๋ฆฌ ๋ฐฉ์๊ณผ Chunk ์งํฅ ์ฒ๋ฆฌ ๋ฐฉ์์ ์ง์ํ๊ณ ์์ต๋๋ค.
@Slf4j
@RequiredArgsConstructor
@Configuration
public class ExampleJobConfig extends **DefaultBatchConfiguration** {
private static final String JOB_NAME = "exampleJob";
private static final String FIRST_STEP_NAME = "firstStep";
@Bean
public Job exampleJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new JobBuilder(JOB_NAME, jobRepository)
.start(firstStep(jobRepository, transactionManager))
.build();
}
@Bean
public Step firstStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder(FIRST_STEP_NAME, jobRepository)
.tasklet((contribution, chunkContext) -> {
log.info(">>>>>>>>>>>>>>>> First step");
return RepeatStatus.FINISHED;
}, transactionManager).build();
}
}
๋ค์๊ณผ ๊ฐ์ด ๊ฐ๋จํ๊ฒ log๋ฅผ ์ถ๋ ฅํ๋ ๊ธฐ๋ฅ์ ๋ง๋ค์ด๋ณด์์ต๋๋ค.
Spring Batch 5.0.0 ์ดํ๋ก๋ extends DetaulBatchConfiguration์ ํตํด ์ค์ ๋ค์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.

์ ์ฌ์ง์์ ์ถ๋ ฅ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
@Bean
public Job multiStepJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new JobBuilder(JOB_NAME, jobRepository)
.start(firstStep(jobRepository, transactionManager))
.next(nextStep(jobRepository, transactionManager))
.next(lastStep(jobRepository, transactionManager))
.build();
}
next ๋ฅผ ํ์ฉํ์ฌ ์ฌ๋ฌ๊ฐ์ step ์ ๊ตฌ์ฑํ์์ต๋๋ค. ์ด๋ ๊ฒ ๋ค์ค์ผ๋ก Step์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.

๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ด 3๊ฐ์ Step์ด ์งํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
์ถํ ์ถ๊ฐํ๊ฒ ์ต๋๋ค.
Step์๋ ๋ค์ํ ์ค์ ์ ์ ์ฉํ ์ ์์ต๋๋ค. ํ๋์ฉ ์์ ์ฝ๋์ ํจ๊ป ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
startlimit ์ฌ์ฉํ๊ธฐstartlimit ๋ ํด๋น Step์ ์คํจ ์ดํ ์ฌ์์ ๊ฐ๋ฅ ํ์๋ฅผ ์๋ฏธํฉ๋๋ค. startlimit ์ดํ ์คํ๋๋ Exception์ด ๋ฐ์๋ฉ๋๋ค.
@Bean
public Step startLimitStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder(START_LIMIT_STEP_NAME, jobRepository)
.tasklet(tasklet(), transactionManager)
.startLimit(10) // 10๋ฒ ์ฌ์์ ๊ฐ๋ฅ
.build();
}
์ด ์ธ์๋ skip, retry, noRollback ์ ๊ฐ์ ๋ค์ํ ์ค์ ๋ค์ด ์์ต๋๋ค.

Tasklet์ ํ๋์ ๋ฉ์๋๋ก ๊ตฌ์ฑ ๋์ด์๋ ๊ฐ๋จํ ์ธํฐํ์ด์ค์ ๋๋ค. ์ด ๋ฉ์๋๋ ์คํจ๋ฅผ ์๋ฆฌ๊ธฐ ์ํด ์์ธ๋ฅผ ๋ฐํํ๊ฑฐ๋ throwํ ๋ ๊น์ง execute๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ํธ์ถํ๊ฒ ๋ฉ๋๋ค. ์ํ๋ ๋๋ง๋ค ๋ ๋ฆฝ์ ์ธ ํธ๋์ญ์ ์ด ์ป์ด์ง๋๋ค.

์ด๊ธฐํ, ์ ์ฅ ํ๋ก์์ ์คํ, ์๋ฆผ ์ ์ก๊ณผ ๊ฐ์ Job์์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. ๊ณ์ ์งํํ ์ง ์๋ ๋๋ผ์ง ๋๊ฐ์ง ๊ฒฝ์ฐ์๋ง ์ ๊ณต๋ฉ๋๋ค.
public enum RepeatStatus {
CONTINUABLE(true), // ๊ณ์ ์งํ
FINISHED(false); // ๋๋ด๊ธฐ
// ETC...
}
Tasklet์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ด 3๊ฐ์ง๊ฐ ์๋๋ฐ ํ๋์ฉ ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
// ๋ด๋ถ ๋๋ค์์ผ๋ก ์์ฑํ๊ธฐ
@Bean
public Step firstStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder(FIRST_STEP_NAME, jobRepository)
.tasklet((contribution, chunkContext) -> {
log.info(">>>>>>>>>>>>>>>> First step");
return RepeatStatus.FINISHED;
}, transactionManager).build();
}
// ํจ์๋ก ๋ถ๋ฆฌํ๊ธฐ
public Tasklet tasklet() {
return ((contribution, chunkContext) -> {
log.info(">>>>>>>>>>>>>>>> Step");
return RepeatStatus.FINISHED;
});
}
์ ์ฝ๋์ ๊ฐ์ด ๋๋ค์์ผ๋ก tasklet์ ์์ฑํ ์ ์์ต๋๋ค.
@RequiredArgsConstructor
@Configuration
public class MethodInvokingTaskletAdapterJobConfig extends DefaultBatchConfiguration {
private final String JOB_NAME = "MethodInvokingTaskletAdapterJob";
private final String STEP_NAME = "SleepBySleepServiceStep";
private final SleepService sleepService;
@Bean
public Job methodInvokingTaskletAdapterJob(
final JobRepository jobRepository,
final PlatformTransactionManager transactionManager
) {
return new JobBuilder(JOB_NAME, jobRepository)
.start(sleepBySleepServiceStep(jobRepository, transactionManager))
.build();
}
@Bean
public Step sleepBySleepServiceStep(
final JobRepository jobRepository,
final PlatformTransactionManager transactionManager
) {
return new StepBuilder(STEP_NAME, jobRepository)
.tasklet(sleepBySleepServiceTasklet(), transactionManager)
.build();
}
// MethodInvokingTaskletAdapter ๋ฐฉ์
@Bean
public MethodInvokingTaskletAdapter sleepBySleepServiceTasklet() {
MethodInvokingTaskletAdapter adapter = new MethodInvokingTaskletAdapter();
adapter.setTargetObject(sleepService);
adapter.setTargetMethod("sleep");
return adapter;
}
}
@Slf4j
@Service
public class SleepService {
public void sleep() throws InterruptedException {
log.info("Sleep Start");
Thread.sleep(500);
}
}
MethodInvokingTaskletAdapter ์ ์ฌ์ฉํ์ฌ ์คํํ๋ ค๊ณ ํ๋ ๋น์ฆ๋์ค ๋ก์ง๊ณผ ํจ์๋ช
์ ์์ฑํ์ฌ ๊ตฌํํ ์ ์์ต๋๋ค.

์คํ์ํค๋ฉด ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
@Slf4j
public class ExternalClassTasklet implements Tasklet, StepExecutionListener {
@Override
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
log.info(">>>>>>>>>> Before Step Start!");
}
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
for (int i = 0; i < 10; i++) {
log.info(">>>>>>>>>>>>>>>>>>>> {}: Execute!", i);
}
return RepeatStatus.FINISHED;
}
@Override
@AfterStep
public ExitStatus afterStep(StepExecution stepExecution) {
log.info(">>>>>>>>>> After Step Start!");
return ExitStatus.COMPLETED;
}
}
๋ค์๊ณผ ๊ฐ์ด Tasklet ์ ๊ตฌํํ์ฌ ์์ฑํ ์ ์์ต๋๋ค.
๋ง์ฝ ์คํ์ด์ ๊ณผ ์ดํ์ ํน์ ๋ก์ง์ด ํ์ํ๋ค๋ฉด StepExecutionListener ์ ์์๋ฐ์ @BeforeStep, @AfterStep์ ํตํด execute ๋ฐฐ์น ์คํ ์ ํ์ Event๋ฅผ ๋ฑ๋กํ์ฌ ์คํ ์ํฌ ์ ์์ต๋๋ค.

๋ค์๊ณผ ๊ฐ์ด ์ ์์ ์ผ๋ก ์คํ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
Spring Batch์์ Chunk๋ ์ฒ๋ฆฌ๋๋ ์ปค๋ฐ ROW์๋ฅผ ์๋ฏธํฉ๋๋ค. Batch ์ฒ๋ฆฌ์์ ์ปค๋ฐ ๋๋ ROW ์๋ผ๋๊ฑด chunk๋จ์๋ก Transaction์ ์ํํ๊ธฐ ๋๋ฌธ์ ์คํจ์ Chunk ๋จ์ ๋งํผ Rollback์ด ๋๊ฒ ๋ฉ๋๋ค.
Chunk ์งํฅ ์ฒ๋ฆฌ์์๋ ๋ค์๊ณผ ๊ฐ์ 3๊ฐ์ง ์๋๋ฆฌ์ค๋ก ์คํ๋ฉ๋๋ค.

์๋ ๊ทธ๋ฆผ์ Chunk ์งํฅ ์ฒ๋ฆฌ์์ ๋ฐฐ์น๊ฐ ์ํ๋๋ ๊ทธ๋ฆผ์ ๋๋ค.

์ฃผ๋ก ์ฌ์ฉํ๋ ์๋์ ์ฌ์ง์ฒ๋ผ ๋ฐฑ๋ง๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆฌ๋ ๊ฒ์ด ๋ถ๋ด๋๊ธฐ ๋๋ฌธ์ ์ฃผ๋ก Chunk ๋จ์๋ก ๋ถํ ํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค.

Spring Batch์๋ ๋ค์ํ ItemReader์ ItemWriter๊ฐ ์กด์ฌํฉ๋๋ค. ๋์ฉ๋ ๋ฐฐ์น ์ฒ๋ฆฌ๋ฅผ ํ๊ฒ ๋๋ฉด Item์ ์ฝ์ด ์ฌ ๋ Paging ์ฒ๋ฆฌ๋ฅผ ํ๋๊ฒ ํจ๊ณผ์ ์ ๋๋ค. Spring Batch Reader์์๋ ์ด๋ฌํ Paging ์ฒ๋ฆฌ๋ฅผ ์ง์ํ๊ณ ์์ต๋๋ค. ๋ํ ์ ์ ํ Paging ์ฒ๋ฆฌ์ Chunk Size๋ฅผ ์ค์ ํ์ฌ ๋์ฑ ํจ๊ณผ์ ์ธ ๋ฐฐ์น ์ฒ๋ฆฌ๋ฅผ ํ ์ ์์ต๋๋ค.
Paging Size์ Chunk Size์ ๊ด๊ณ๋ ๋ค์๊ณผ ๊ฐ์ ๊ด๊ณ๋ก ์ด๋ฃจ์ด์ง๋๋ค.
Paging Size๊ฐ 5์ด๋ฉฐ Chunk Size๊ฐ 10์ผ ๊ฒฝ์ฐ 2๋ฒ์ Read๊ฐ ์ด๋ฃจ์ด์ง ํ์ 1๋ฒ์ ํธ๋์ญ์ ์ด ์ํ๋ฉ๋๋ค. ์ด๋ ํ๋ฒ์ ํธ๋์ญ์ ์ ์ํด ์ฟผ๋ฆฌ ์ํ์ด ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
ํ์ง๋ง ํน๋ณํ ์ด์ ๊ฐ ์๋ ํ Paging Size์ Chunk Size๋ฅผ ๋์ผํ๊ฒ ํ๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค.
Setting a fairly large page size and using a commit interval that matches the page size should provide better performance.
ํ์ด์ง ํฌ๊ธฐ๋ฅผ ์๋นํ ํฌ๊ฒ ์ค์ ํ๊ณ ํ์ด์ง ํฌ๊ธฐ์ ์ผ์นํ๋ ์ปค๋ฐ ๊ฐ๊ฒฉ์ ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ์ด ํฅ์๋ฉ๋๋ค.
์ถ์ฒ: Spring Batch
Spring Batch์๋ 6๊ฐ์ Meta Table์ 3๊ฐ์ Sequence Table์ด ์กด์ฌํฉ๋๋ค. ์ด๋ Spring BatchJob์ด ์คํ ๋ ๋๋ง๋ค Job์ ๋ํ ๋ค์ํ ์ ๋ณด๋ค์ด ์ ์ฅ๋๊ฒ ๋ฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก๋ ํด๋น Meta Table์ด ์์ด๋ Spring Batch Framework๋ฅผ ์คํ์ํฌ ์ ์์ผ๋ ์ด๋ ํ์์ ๋ฐ๋ผ ์ปค์คํฐ๋ง์ด์ง์ ํตํด Meta Table์ด ์์ด๋ ์คํ๋๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.

SEQUENCE
BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION๋ฐ BATCH_STEP_EXECUTION์ Primary Key๋ ์ํ์ค์ ์ํด ์์ฑ๋ฉ๋๋ค. ๋ค์์ Sequence๋ฅผ ์ง์ํ๋ Database Create ์์ ๋๋ค.
BATCH_JOB_INSTANCE
BATCH_JOB_INSTANCE ํ ์ด๋ธ์๋ JobInstance์ ๊ด๋ จ๋ ๋ชจ๋ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ๋ํ ํด๋น Table์ ์ ์ฒด ๊ณ์ธต ๊ตฌ์กฐ์ ์ต์์ ์ญํ ์ ํฉ๋๋ค.
BATCH_JOB_EXECUTION_PARAMS
BATCH_JOB_EXECUTION_PARAMSย ํ ์ด๋ธ์๋ Job์ ์คํ ์ํฌ ๋ ์ฌ์ฉํ๋ JobParameters์ ๋ํ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์์ต๋๋ค.
BATCH_JOB_EXECUTION
BATCH_JOB_EXECUTIONํ ์ด๋ธ์๋ JobExcution์ ๊ด๋ จ๋ ๋ชจ๋ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์์ต๋๋ค. JobExcution์ JobInstance๊ฐ ์คํ ๋ ๋๋ง๋ค ์์์๊ฐ, ์ข ๋ฃ์๊ฐ, ์ข ๋ฃ์ฝ๋ ๋ฑ ๋ค์ํ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
BATCH_STEP_EXECUTION
BATCH_JOB_EXECUTIONํ ์ด๋ธ์๋ StepExecution์ ๋ํ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์์ต๋๋ค. BATCH_JOB_EXECUTION ํ ์ด๋ธ๊ณผ ์ฌ๋ฌ ๋ฉด์์ ์ ์ฌํ๋ฉฐ STEP์ EXECUTION ์ ๋ณด์ธ ์ฝ์ ์, ์ปค๋ฐ ์, ์คํต ์ ๋ฑ ๋ค์ํ ์ ๋ณด๋ฅผ ์ถ๊ฐ๋ก ๋ด๊ณ ์์ต๋๋ค.
BATCH_JOB_EXECUTION_CONTEXT
BATCH_JOB_EXECUTION_CONTEXTํ ์ด๋ธ์๋ JobExecution์ExecutionContext ์ ๋ณด๊ฐ ๋ค์ด์์ต๋๋ค.์ด ExecutionContext ๋ฐ์ดํฐ๋ ์ผ๋ฐ์ ์ผ๋ก JobInstance๊ฐ ์คํจ ์ ์ค๋จ๋ ์์น์์ ๋ค์ ์์ํ ์ ์๋ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์์ต๋๋ค.
BATCH_STEP_EXECUTION_CONTEXT
BATCH_STEP_EXECUTION_CONTEXTํ ์ด๋ธ์๋ StepExecution์ ExecutionContext ์ ๋ณด๊ฐ ๋ค์ด์์ต๋๋ค. ์ด ExecutionContext ๋ฐ์ดํฐ๋ ์ผ๋ฐ์ ์ผ๋ก JobInstance๊ฐ ์คํจ ์ ์ค๋จ๋ ์์น์์ ๋ค์ ์์ํ ์ ์๋ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์์ต๋๋ค.