Skip to content

springframework-storage/SpringBoot-Batch-Demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

11 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

SpringBoot-Batch


Spring Batch ์˜ ๋ฉ”ํƒ€ ํ…Œ์ด๋ธ”

Batch_Job_Instance

  • Job Parameter ์— ๋”ฐ๋ผ ์ƒ์„ฑ๋˜๋Š” ํ…Œ์ด๋ธ”
  • Spring Batch ๊ฐ€ ์‹คํ–‰๋  ๋•Œ, ์™ธ๋ถ€์—์„œ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ
  • ๋™์ผํ•œ Job Parameter ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ ์กด์žฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

Batch_Job_Execution

  • Job_Execution ๊ณผ Job_Instance ๋Š” ์ž์‹ - ๋ถ€๋ชจ ๊ด€๊ณ„
  • Job_Execution ์€ ์ž์‹ ์˜ ๋ถ€๋ชจ Job_Instance ๊ฐ€ ์„ฑ๊ณต/์‹คํŒจํ–ˆ๋˜ ๋ชจ๋“  ๋‚ด์—ญ์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.
  • ๋™์ผํ•œ Job Parameter ๋กœ ์„ฑ๊ณตํ•œ ๊ธฐ๋ก์ด ์žˆ์„ ๋•Œ๋งŒ ์žฌ์ˆ˜ํ–‰์„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Batch_Job_Execution_Params

  • Batch_Job_Execution ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋  ๋‹น์‹œ ์ž…๋ ฅ ๋ฐ›์€ Job Parameter ๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

์กฐ๊ฑด๋ณ„ ํ๋ฆ„ ์ œ์–ด (Flow)

Batch Status vs. Exit Status

  • BatchStatus: Job ๋˜๋Š” Step ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ Spring ์—์„œ ๊ธฐ๋กํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Enum
    • BatchStatus ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ’: COMPLETED, STARTING, STARTED, STOPPED, FAILED, ABANDONED, UNKNOWN
  • ExitStatus: Step ์˜ ์‹คํ–‰ ํ›„ ์ƒํƒœ
    • .on("FAILED").to(stepB()) ์ฝ”๋“œ์—์„œ on ๋ฉ”์†Œ๋“œ๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์€ BatchStatus ๊ฐ€ ์•„๋‹ˆ๊ณ , ์‹ค์ œ ์ฐธ์กฐ๋˜๋Š” ๊ฐ’์€ Step ์˜ ExitStatus ์ž…๋‹ˆ๋‹ค.
    • ExitStatus ๋Š” Enum ์ด ์•„๋‹™๋‹ˆ๋‹ค.
    • Spring Batch ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ExitStatus ์˜ exitCode ๋Š” Step ์˜ BatchStatus ์™€ ๊ฐ™๋„๋ก ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

JobExecutionDecider

  • Step ๋“ค์˜ Flow ์†์—์„œ ๋ถ„๊ธฐ๋งŒ ๋‹ด๋‹นํ•˜๋Š” ํƒ€์ž…

Scope & Job Parameter

  • ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” Scope ๋ž€ @StepScope, @JobScope ์ž…๋‹ˆ๋‹ค.
  • Spring Batch ์˜ ๊ฒฝ์šฐ ์™ธ๋ถ€ ๋˜๋Š” ๋‚ด๋ถ€์—์„œ Parameter ๋ฅผ ๋ฐ›์•„ ์—ฌ๋Ÿฌ Batch ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ Job Parameter ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  • Job Parameter ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•ญ์ƒ Spring Batch ์ „์šฉ Scope ๋ฅผ ์„ ์–ธํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด SpEL ๋กœ ์„ ์–ธํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
    • @Value("#{jobParameters[ํŒŒ๋ผ๋ฏธํ„ฐ๋ช…]}")
    • jobParameters ์™ธ์—๋„ jobExecutionContext, stepExecutionContext ๋“ฑ๋„ SpEL ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • @JobScope ์—์„œ๋Š” stepExecutionContext ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ณ , jobParameters, jobExecutionContext ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@StepScope & @JobScope

  • Spring Batch ๋Š” @StepScope, @JobScope ๋ผ๋Š” ์•„์ฃผ ํŠน๋ณ„ํ•œ Bean Scope ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

    • ( Spring Bean ์˜ ๊ธฐ๋ณธ Scope ๋Š” singleton )
  • Spring Batch ์ปดํฌ๋„ŒํŠธ (Tasklet, ItemReader, ItemWriter, ItemProcessor ๋“ฑ)์— @StepScope ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด

  • Spring Batch ๊ฐ€ Spring ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ†ตํ•ด ์ง€์ •๋œ Step ์˜ ์‹คํ–‰ ์‹œ์ ์— ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ Spring Bean ์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  • @JobScope ๋Š” Job ์‹คํ–‰ ์‹œ์ ์— Bean ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

  • ์ฆ‰, Bean ์˜ ์ƒ์„ฑ ์‹œ์ ์„ ์ง€์ •๋œ Scope ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์œผ๋กœ ์ง€์—ฐ์‹œํ‚ต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ Bean ์˜ ์ƒ์„ฑ ์‹œ์ ์„ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ์ ์ด ์•„๋‹Œ, Step ํ˜น์€ Job ์˜ ์‹คํ–‰ ์‹œ์ ์œผ๋กœ ์ง€์—ฐ์‹œํ‚ด์œผ๋กœ์จ ์–ป๋Š” ์žฅ์ ์€ ํฌ๊ฒŒ 2๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ฒซ์งธ, Job Parameter ์˜ Late Binding ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • Job Parameter ๋ฅผ StepContext ๋˜๋Š” JobExecutionContext ๋ ˆ๋ฒจ์—์„œ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ผญ Application ์ด ์‹คํ–‰๋˜๋Š” ์‹œ์ ์ด ์•„๋‹ˆ๋”๋ผ๋„ Controller, Service ์™€ ๊ฐ™์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ ๋‹จ๊ณ„์—์„œ Job Parameter ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋‘˜์งธ, ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณ‘๋ ฌ ํ˜น์€ ๋™์‹œ์— ์‚ฌ์šฉํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • Step ์•ˆ์— Tasklet ์ด ์žˆ๊ณ , ์ด Tasklet ์—๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์™€ ์ด ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋กœ์ง์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๊ฒฝ์šฐ @StepScope ์—†์ด Step ์„ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰์‹œํ‚ค๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ Step ์—์„œ ํ•˜๋‚˜์˜ Tasklet ์„ ๋‘๊ณ  ๋งˆ๊ตฌ์žก์ด๋กœ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
    • ํ•˜์ง€๋งŒ, @StepScope ๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ฐ๊ฐ์˜ Step ์—์„œ ๋ณ„๋„์˜ Tasklet ์„ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋กœ์˜ ์ƒํƒœ๋ฅผ ์นจ๋ฒ”ํ•  ์ผ์ด ์—†์Šต๋‹ˆ๋‹ค.

Job Parameter

  • Job Parameters ๋Š” @Value ๋ฅผ ํ†ตํ•ด์„œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • Job Parameters ๋Š” Step ์ด๋‚˜, Tasklet, Reader ๋“ฑ Batch ์ปดํฌ๋„ŒํŠธ Bean ์˜ ์ƒ์„ฑ ์‹œ์ ์— ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ •ํ™•ํžˆ๋Š” @StepScope, @JobScope Bean ์„ ์ƒ์„ฑํ•  ๋•Œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Chunk ์ง€ํ–ฅ ์ฒ˜๋ฆฌ

Spring Batch ์˜ ํฐ ์žฅ์  ์ค‘ ํ•˜๋‚˜๋กœ Chunk ์ง€ํ–ฅ ์ฒ˜๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Chunk

  • Spring Batch ์—์„œ์˜ Chunk ๋ž€ ๋ฐ์ดํ„ฐ ๋ฉ์–ด๋ฆฌ๋กœ, ์ž‘์—…ํ•  ๋•Œ ๊ฐ ์ปค๋ฐ‹ ์‚ฌ์ด์— ์ฒ˜๋ฆฌ๋˜๋Š” row ์ˆ˜๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.
  • ์ฆ‰, Chunk ์ง€ํ–ฅ ์ฒ˜๋ฆฌ๋ž€ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด Chunk ๋ผ๋Š” ๋ฉ์–ด๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ , Chunk ๋‹จ์œ„๋กœ ํŠธ๋žœ์žญ์…˜์„ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • Chunk ๋‹จ์œ„๋กœ ํŠธ๋žœ์žญ์…˜์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹คํŒจํ•  ๊ฒฝ์šฐ ํ•ด๋‹น Chunk ๋งŒํผ๋งŒ ๋กค๋ฐฑ๋˜๊ณ , ์ด์ „์— ์ปค๋ฐ‹๋œ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๊นŒ์ง€๋Š” ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค.
  • Reader ์™€ Processor ์—์„œ๋Š” 1๊ฑด์”ฉ ๋‹ค๋ค„์ง€๊ณ , Writer ์—์„  Chunk ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

ChunkOrientedTasklet

  • Chunk ์ง€ํ–ฅ ์ฒ˜๋ฆฌ์˜ ์ „์ฒด ๋กœ์ง์„ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์€ ChunkOrientedTasklet ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
  • ChunkOrientedTasklet ์˜ execute() ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€ ์ฝ”๋“œ
    • chunkProvider.provide() ๋กœ Reader ์—์„œ Chunk Size ๋งŒํผ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    • chunkProcessor.process() ์—์„œ Reader ๋กœ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณต(Processor)ํ•˜๊ณ  ์ €์žฅ(Writer)ํ•ฉ๋‹ˆ๋‹ค.
  • chunkProvider.provide() ๋‚ด๋ถ€
    • inputs ๊ฐ€ Chunk Size ๋งŒํผ ์Œ“์ผ ๋•Œ๊นŒ์ง€ read() ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
    • ์‹ค์ œ๋กœ๋Š” ItemReader.read ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
    • ์ฆ‰, ItemReader.read ์—์„œ 1๊ฑด์”ฉ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด Chunk Size ๋งŒํผ ๋ฐ์ดํ„ฐ๋ฅผ ์Œ“๋Š” ๊ฒƒ์ด provide() ๊ฐ€ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

SimpleChunkProcessor

  • Processor ์™€ Writer ๋กœ์ง์„ ๋‹ด๊ณ  ์žˆ๋Š” ๊ฒƒ์€ ChunkProcessor ๊ฐ€ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • ChunkProcessor ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ ๊ตฌํ˜„์ฒด๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด SimpleChunkProcessor ์ž…๋‹ˆ๋‹ค.
  • ์ฒ˜๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ํ•ต์‹ฌ ๋กœ์ง์€ process()์ž…๋‹ˆ๋‹ค.
    • Chunk<I> inputs ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
      • ์ด ๋ฐ์ดํ„ฐ๋Š” ์•ž์„œ chunkProvider.provide() ์—์„œ ๋ฐ›์€ Chunk Size ๋งŒํผ ์Œ“์ธ item ์ž…๋‹ˆ๋‹ค.
    • transform() ์—์„œ๋Š” ์ „๋‹ฌ ๋ฐ›์€ inputs ์„ doProcess() ๋กœ ์ „๋‹ฌํ•˜๊ณ  ๋ณ€ํ™˜๊ฐ’์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.
    • transform() ์„ ํ†ตํ•ด ๊ฐ€๊ณต๋œ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋Š” write() ๋ฅผ ํ†ตํ•ด ์ผ๊ด„ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
      • write() ๋Š” ์ €์žฅ์ด ๋  ์ˆ˜๋„ ์žˆ๊ณ , ์™ธ๋ถ€ API ๋กœ ์ „์†กํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
      • ์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ItemWriter ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋Š”์ง€์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
    • ์—ฌ๊ธฐ์„œ transform() ์€ ๋ฐ˜๋ณต๋ฌธ์„ ํ†ตํ•ด doProcess() ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
      • ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋Š” ItemProcessor ์˜ process() ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
      • doProcess() ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ๋งŒ์•ฝ ItemProcessor ๊ฐ€ ์—†๋‹ค๋ฉด, ์ฆ‰ item ์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ItemProcessor ์˜ process() ๋กœ ๊ฐ€๊ณตํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ๊ฐ€๊ณต๋œ ๋ฐ์ดํ„ฐ๋“ค์€ SimpleChunkProcessor ์˜ doWrite() ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Page Size vs Chunk Size

๊ธฐ์กด์˜ Spring Batch ์—์„œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋˜ PagingItemReader ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Chunk Size ๋Š” ํ•œ๋ฒˆ์— ์ฒ˜๋ฆฌ๋  ํŠธ๋žœ์žญ์…˜ ๋‹จ์œ„
  • Page Size ๋Š” ํ•œ๋ฒˆ์— ์กฐํšŒํ•  Item ์˜ ์–‘

PagingItemReader ์˜ ๋ถ€๋ชจ ํด๋ž˜์Šค์ธ AbstractItemCountingItemStreamItemReader ์˜ read() ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€

  • ์ฝ์–ด์˜ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด doRead() ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
    • doRead() ์—์„œ๋Š” ํ˜„์žฌ ์ฝ์–ด์˜ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๊ฑฐ๋‚˜, Page Size ๋ฅผ ์ดˆ๊ณผํ•œ ๊ฒฝ์šฐ doReadPage() ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
      • ์ฝ์–ด์˜ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๋Š” read ๊ฐ€ ์ฒ˜์Œ ์‹œ์ž‘ํ•  ๋•Œ๋Š” ๋งํ•ฉ๋‹ˆ๋‹ค.
      • Page Size ๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ๊ฒฝ์šฐ๋Š” Page Size ๊ฐ€ 10์ธ๋ฐ, ์ฝ์–ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ 11๋ฒˆ์งธ ๋ฐ์ดํ„ฐ์ธ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.
      • ์ฆ‰, Page ๋‹จ์œ„๋กœ ๋Š์–ด์„œ ์กฐํšŒํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
    • doReadPage() ๋ถ€ํ„ฐ๋Š” ํ•˜์œ„ ๊ตฌํ˜„ ํด๋ž˜์Šค์—์„œ ๊ฐ์ž๋งŒ์˜ ๋ฐฉ์‹์œผ๋กœ ํŽ˜์ด์ง• ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
      • ๋ณดํŽธ์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ JpaPagingItemReader ์ž…๋‹ˆ๋‹ค.

JpaPagingItemReader ์˜ doReadPage() ์˜ ์ฝ”๋“œ

  • Reader ์—์„œ ์ง€์ •ํ•œ Page Size ๋งŒํผ offSet, limit ๊ฐ’์„ ์ง€์ •ํ•˜์—ฌ ํŽ˜์ด์ง• ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑ(createQuery())ํ•˜๊ณ , ์‚ฌ์šฉ (query.getResultList())ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฟผ๋ฆฌ ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” results ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ์ €์žฅ๋œ results ์—์„œ read() ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์–ด ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ Page Size ๊ฐ€ 10, Chunk Size ๊ฐ€ 50 ์ด๋ผ๋ฉด

  • ItemReader ์—์„œ Page ์กฐํšŒ๊ฐ€ 5๋ฒˆ ์ผ์–ด๋‚ฌ์„ ๋•Œ, 1๋ฒˆ์˜ ํŠธ๋žœ์žญ์…˜์ด ๋ฐœ์ƒํ•˜์—ฌ Chunk ๊ฐ€ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  • ํ•œ ๋ฒˆ์˜ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด 5๋ฒˆ์˜ ์ฟผ๋ฆฌ ์กฐํšŒ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ƒ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ทธ๋ž˜์„œ Spring Batch ์˜ PagingItemReader ์—๋Š” ์ƒ๋‹นํžˆ ํฐ ํŽ˜์ด์ง€ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•˜๊ณ  ํŽ˜์ด์ง€ ํฌ๊ธฐ์™€ ์ผ์น˜ํ•˜๋Š” ์ปค๋ฐ‹ ๊ฐ„๊ฒฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค. ๋ผ๋Š” ์ฃผ์„์ด ์ž‘์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • 2๊ฐœ ๊ฐ’์„ ์ผ์น˜์‹œํ‚ค๋Š” ๊ฒƒ์ด ๋ณดํŽธ์ ์œผ๋กœ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋ฏ€๋กœ ์ผ์น˜์‹œํ‚ค๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.

ItemReader

  • ์œ„ ๊ณผ์ •์„ ํ†ตํ•ด Spring Batch ๊ฐ€ Chunk ์ง€ํ–ฅ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ด๋Š” Job ๊ณผ Step ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Œ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.
  • Step ์€ Tasklet ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ๋˜๊ณ , Tasklet ์ค‘์—์„œ ChunkOrientedTasklet ์„ ํ†ตํ•ด Chunk ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉฐ ์ด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” 3 ์š”์†Œ๋กœ ItemReader, ItemWriter, ItemProcessor ๊ฐ€ ์žˆ์Œ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

    ์ฆ‰, ItemReader, ItemWriter, ItemProcessor ์˜ ๋ฌถ์Œ ์—ญ์‹œ Tasklet ์ด๋ž€ ์–˜๊ธฐ์ž…๋‹ˆ๋‹ค.
    ์ด๋“ค์˜ ๋ฌถ์Œ์„ ChunkOrientedTasklet ์—์„œ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

ItemReader ์†Œ๊ฐœ

  • ItemReader ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. ๊ผญ DB ์˜ ๋ฐ์ดํ„ฐ๋งŒ์„ ์ด์•ผ๊ธฐํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

  • Spring Batch ์—์„œ ์ง€์›ํ•˜์ง€ ์•Š๋Š” Reader ๊ฐ€ ํ•„์š”ํ•  ๊ฒฝ์šฐ ์ง์ ‘ ํ•ด๋‹น Reader ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Spring Batch ์˜ Reader ์—์„œ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์œ ํ˜•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    • ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์—์„œ ์ฝ์–ด์˜ค๊ธฐ
    • ํŒŒ์ผ์—์„œ ์ฝ์–ด์˜ค๊ธฐ
    • DB ์—์„œ ์ฝ์–ด์˜ค๊ธฐ
    • JMS ๋“ฑ ๋‹ค๋ฅธ ์†Œ์Šค์—์„œ ์ฝ์–ด์˜ค๊ธฐ
    • ๋ณธ์ธ๋งŒ์˜ ์ปค์Šคํ…€ํ•œ Reader ๋กœ ์ฝ์–ด์˜ค๊ธฐ
  • ItemReader ์˜ ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ๊ตฌํ˜„์ฒด๋Š” JdbcPagingItemReader ์ž…๋‹ˆ๋‹ค

    • ItemReader ์™ธ์— ItemStream ์ธํ„ฐํŽ˜์ด์Šค๋„ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    • ItemReader ๋Š” read() ๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๋Š” ๋ฉ”์†Œ๋“œ๋งŒ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    • **ItemStream ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ฃผ๊ธฐ์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ์ƒํƒœ์—์„œ ๋ณต์›ํ•˜๊ธฐ ์œ„ํ•œ Marker ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋ฐฐ์น˜ ํ”„๋กœ์„ธ์Šค์˜ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์™€ ์—ฐ๊ณ„ํ•ด์„œ ItemReader ์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ณ  ์‹คํŒจํ•œ ๊ณณ์—์„œ ๋‹ค์‹œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
      • ItemStream ์˜ 3๊ฐœ ๋ฉ”์†Œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

        open(), close() ๋Š” ์ŠคํŠธ๋ฆผ์„ ์—ด๊ณ  ๋‹ซ์Šต๋‹ˆ๋‹ค.
        update() ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Batch ์ฒ˜๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ๊ฐœ๋ฐœ์ž๋Š” ItemReader ์™€ ItemStream ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์—ฌ ์›ํ•˜๋Š” ํ˜•ํƒœ์˜ ItemReader ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Database Reader

Spring Framework ์˜ ๊ฐ•์  ์ค‘ ํ•˜๋‚˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก JDBC ์™€ ๊ฐ™์€ ๋ฌธ์ œ์ ์„ ์ถ”์ƒํ™”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ์„œ๋น„์Šค ์ถ”์ƒํ™”๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ Spring Batch ๋Š” Spring Framework ์˜ JDBC ๊ธฐ๋Šฅ์„ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐฐ์น˜ ์ž‘์—…์€ ๋งŽ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ JdbcTemplate ๋Š” ๋ถ„ํ•  ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— (์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜) ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ limit, offset ์„ ์‚ฌ์šฉํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • Spring Batch ๋Š” ์ด๋Ÿฐ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด 2๊ฐœ์˜ Reader ํƒ€์ž…์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • Cursor ๋Š” ์‹ค์ œ๋กœ JDBC ResultSet ์˜ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
    • ResultSet ์ด open ๋  ๋•Œ๋งˆ๋‹ค next() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์–ด DB ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.
    • ์ด๋ฅผ ํ†ตํ•ด ํ•„์š”์— ๋”ฐ๋ผ DB ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ Streaming ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • Cursor ๋ฐฉ์‹์€ DB ์™€ ์ปค๋„ฅ์…˜์„ ๋งบ์€ ํ›„, Cursor ๋ฅผ ํ•œ์นธ์”ฉ ์˜ฎ๊ธฐ๋ฉด์„œ ์ง€์†์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    • Cursor ๊ธฐ๋ฐ˜ ItemReader ๊ตฌํ˜„์ฒด
      • JdbcCursorItemReader
      • HibernateCursorItemReader
      • StoredProcedureItemReader
  • ๋ฐ˜๋ฉด Paging ์€ ์ข€ ๋” ๋งŽ์€ ์ž‘์—…์„ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค.
    • Paging ๊ฐœ๋…์€ ํŽ˜์ด์ง€๋ผ๋Š” Chunk ๋กœ DB ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
    • ์ฆ‰, ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ ํ•œ๋ฒˆ์— ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.
    • Paging ๋ฐฉ์‹์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง€์ •ํ•œ Page Size ๋งŒํผ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    • Paging ๊ธฐ๋ฐ˜ ItemReader ๊ตฌํ˜„์ฒด
      • JdbcPagingItemReader
      • HibernatePagingItemReader
      • JpaPagingItemReader

CursorItemReader (JdbcCursorItemReader)

JPA ์—๋Š” CursorItemReader ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

CursorItemReader ์ฃผ์˜์‚ฌํ•ญ

  • DB ์™€ SocketTimeout ์„ ์ถฉ๋ถ„ํžˆ ํฐ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.
  • Cursor ๋Š” ํ•˜๋‚˜์˜ Connection ์œผ๋กœ Batch ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— Batch ๊ฐ€ ๋๋‚˜๊ธฐ ์ „์— DB ์™€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ Connection ์ด ๋จผ์ € ๋Š์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ทธ๋ž˜์„œ Batch ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ์—๋Š” PageItemReader ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค.
  • Paging ์˜ ๊ฒฝ์šฐ ํ•œ ํŽ˜์ด์ง€๋ฅผ ์ฝ์„ ๋•Œ๋งˆ๋‹ค Connection ์„ ๋งบ๊ณ  ๋Š๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด๋ฆฌ ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ผ๋„ ํƒ€์ž„์•„์›ƒ๊ณผ ๋ถ€ํ•˜ ์—†์ด ์ˆ˜ํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

PagingItemReader (JdbcPagingItemReader)

  • DB Cursor ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๊ฐ ์ฟผ๋ฆฌ๊ฐ€ ๊ฒฐ๊ณผ์˜ ์ผ๋ถ€๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์ด๋Ÿฐ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ Paging ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  • Spring Batch ์—์„œ๋Š” offset, limit ์„ PageSize ์— ๋งž๊ฒŒ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • ๋‹ค๋งŒ ๊ฐ ์ฟผ๋ฆฌ๋Š” ๊ฐœ๋ณ„์ ์œผ๋กœ ์‹คํ–‰ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฐ ํŽ˜์ด์ง€๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฏ€๋กœ ํŽ˜์ด์ง• ์‹œ ๊ฒฐ๊ณผ๋ฅผ ์ •๋ ฌํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฐ์ดํ„ฐ ๊ฒฐ๊ณผ์˜ ์ˆœ์„œ๊ฐ€ ๋ณด์žฅ๋  ์ˆ˜ ์žˆ๋„๋ก order by ๊ฐ€ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.
  • JdbcPagingItemReaderJobConfiguration

  • ์ฟผ๋ฆฌ ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด LIMIT 10 ์ด ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ž‘์„ฑํ•œ ์ฝ”๋“œ์—๋Š” Limit ์„ ์–ธ์ด ์—†์Œ)

  • JdbcPagingItemReader ์—์„œ ์„ ์–ธ๋œ fetchSize ์— ๋งž๊ฒŒ ์ž๋™์œผ๋กœ ์ฟผ๋ฆฌ์— ์ถ”๊ฐ€ํ•ด์คฌ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

  • ๋งŒ์•ฝ ์กฐํšŒํ•  ๋ฐ์ดํ„ฐ๊ฐ€ 10๊ฐœ ์ด์ƒ์ด๋ผ๋ฉด offset ์œผ๋กœ ์ ์ ˆํ•˜๊ฒŒ ๋‹ค์Œ fetchSize ๋งŒํผ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JpaPagingItemReader

JPA ๋Š” Hibernate ์™€ ๋งŽ์€ ์œ ์‚ฌ์ ์„ ๊ฐ–๊ณ  ์žˆ์ง€๋งŒ, ํ•œ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๊ฒƒ์ด ์žˆ๋‹ค๋ฉด Hibernate ์—์„  Cursor ๊ฐ€ ์ง€์›๋˜์ง€๋งŒ JPA ์—์„œ Cursor ๊ธฐ๋ฐ˜ DB ์ ‘๊ทผ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

PagingItemReader ์ฃผ์˜์‚ฌํ•ญ

  • ์ •๋ ฌ order ๊ฐ€ ๋ฌด์กฐ๊ฑด ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ Chunk ๋กœ ๋ถ„ํ•  ์กฐํšŒํ•œ๋‹ค๋ฉด, ๋งŒ์•ฝ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๊ฐ€ 4๋งŒ๊ฑด์ด๊ณ  Chunk Size ๊ฐ€ 1๋งŒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ด๋ด…๋‹ˆ๋‹ค.
    • 4๋ฒˆ์˜ ์ฟผ๋ฆฌ๊ฐ€ limit ์˜ ์‹œ์ž‘ ํฌ์ธํŠธ๋งŒ ๋ณ€๊ฒฝ๋œ ์ฑ„ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.
    • ๊ฐ๊ฐ ๋ณ„๋„๋กœ ์ˆ˜ํ–‰๋˜๋Š” ์ฟผ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ •๋ ฌ ๊ธฐ์ค€์ด ์ •ํ•ด์ ธ ์žˆ์ง€ ์•Š๋‹ค๋ฉด ์ฟผ๋ฆฌ๋งˆ๋‹ค ๊ฐ์ž์˜ ์ •๋ ฌ ๊ธฐ์ค€์„ ๋งŒ๋“ค์–ด ์‹คํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    • ์ด๊ฒƒ์œผ๋กœ ์ธํ•ด ์›ํ–ˆ๋˜ ๊ฒฐ๊ณผ๋ฅผ ์–ป์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ…

  • Order by
    • ๊ฐ€์žฅ ๋ณดํŽธ์ ์ธ ๋ฐฉ๋ฒ•์€ order by id ์™€ ๊ฐ™์ด queryString ์— ๊ณ ์œ ํ•œ ์ •๋ ฌ ๊ธฐ์ค€์„ ํฌํ•จ
  • CursorItemReader
    • JPA ์˜ ๊ตฌํ˜„์ฒด๋Š” ์—†์ง€๋งŒ, Jdbc, Hibernate, MyBatis ์—๋Š” CursorItemReader ๋ผ๋Š” Reader ๊ตฌํ˜„์ฒด๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
    • ResultSet ๊ณผ ์ง์ ‘ ์—ฐ๋™ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๋Š” ๊ฒƒ์ธ๋ฐ, ์ผ์ข…์˜ stream ๊ณผ ๊ฐ™๋‹ค๊ณ  ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
    • ์‚ฌ์‹ค์ƒ ์ „์ฒด๋ฅผ ์กฐํšŒํ•˜์—ฌ stream ์ฒ˜๋Ÿผ ์ง€์†์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ์‹์ด๊ธฐ์— ํŽ˜์ด์ง• ์ด์Šˆ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    • ์„ฑ๋Šฅ ๋˜ํ•œ PagingItemReader ๋ณด๋‹ค ์ข‹์Šต๋‹ˆ๋‹ค.
    • ํ•˜์ง€๋งŒ, ๋ฌด์กฐ๊ฑด Cursor ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • ํ•œ๋ฒˆ์— ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ์ดํ„ฐ์˜ ์–‘์ด ๋งŽ์„ ๊ฒฝ์šฐ Batch ๊ฐ€ ๋ป—์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • Paging ํ•ด์„œ ์กฐํšŒํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ „์ฒด ์กฐํšŒ ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ๊ฐ€ ํด ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • Thread Safe ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
      • Multi Thread ๋กœ Batch ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด PagingItemReader ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

ItemReader ์ฃผ์˜์‚ฌํ•ญ

  • JpaRepository ๋ฅผ ListItemReader, QueueItemReader ์— ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค.
    • new ListItemReader<>(jpaRepository.findByAge(age)) ๋กœ Reader ๋กœ ๊ตฌํ˜„ํ•  ๊ฒฝ์šฐ
      • Spring Batch ์˜ ์žฅ์ ์ธ Paging & Cursor ๊ตฌํ˜„์ด ์—†์–ด ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

        ๋ฌผ๋ก  Chunk ๋‹จ์œ„ ํŠธ๋žœ์žญ์…˜์€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

    • ๋งŒ์•ฝ JpaRepository ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด, RepositoryItemReader ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.
      • Paging ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
    • Hibernate, JPA ๋“ฑ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•œ Reader ์‚ฌ์šฉ์‹œ fetchSize ์™€ chunkSize ๋Š” ๊ฐ™์€ ๊ฐ’์„ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ItemWriter

  • Writer ๋Š” Reader, Processor ์™€ ํ•จ๊ป˜ ChunkOrientedTasklet ์„ ๊ตฌ์„ฑํ•˜๋Š” 3 ์š”์†Œ์ž…๋‹ˆ๋‹ค.
  • Reader ์™€ Writer ๋Š” ChunkOrientedTasklet ์—์„œ ํ•„์ˆ˜ ์š”์†Œ์ด๊ณ , Processor ๋Š” ์„ ํƒ์ž…๋‹ˆ๋‹ค.

ItemWriter ์†Œ๊ฐœ

  • ItemWriter ๋Š” Spring Batch ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ถœ๋ ฅ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
  • Spring Batch ๊ฐ€ ์ฒ˜์Œ ๋‚˜์™”์„ ๋•Œ, ItemWriter ๋Š” ItemReader ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ item ์„ ํ•˜๋‚˜์”ฉ ๋‹ค๋ค˜์Šต๋‹ˆ๋‹ค.
  • Spring Batch 2 ์™€ Chunk ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ์˜ ๋„์ž…์œผ๋กœ ์ธํ•ด ItemWriter ์—๋„ ํฐ ๋ณ€ํ™”๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค.
  • ์ด ์—…๋ฐ์ดํŠธ ์ดํ›„ ItemWriter ๋Š” item ํ•˜๋‚˜๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ  Chunk ๋‹จ์œ„๋กœ ๋ฌถ์ธ item List ๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค.
    • ItemReader ๋ฅผ ํ†ตํ•ด ๊ฐ ํ•ญ๋ชฉ์„ ๊ฐœ๋ณ„์ ์œผ๋กœ ์ฝ๊ณ  ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ItemProcessor ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ํ”„๋กœ์„ธ์Šค๋Š” Chunk ์˜ Item ๊ฐœ์ˆ˜๋งŒํผ ์ฒ˜๋ฆฌ๋  ๋•Œ๊นŒ์ง€ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค.
    • Chunk ๋‹จ์œ„๋งŒํผ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด Writer ์— ์ „๋‹ฌ๋˜์–ด Writer ์— ๋ช…์‹œ๋˜์–ด ์žˆ๋Š”๋Œ€๋กœ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • ์ฆ‰, Reader ์™€ Processor ๋ฅผ ๊ฑฐ์ณ ์ฒ˜๋ฆฌ๋œ Item ์„ Chunk ๋‹จ์œ„๋งŒํผ ์Œ“์€ ๋’ค ์ด๋ฅผ Writer ์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • Spring Batch ๋Š” ๋‹ค์–‘ํ•œ Output ํƒ€์ž…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŽ์€ Writer ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Database Writer

  • Java ์„ธ๊ณ„์—์„œ๋Š” JDBC ๋˜๋Š” ORM ์„ ์‚ฌ์šฉํ•ด RDBMS ์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.
  • Spring Batch ๋Š” JDBC ์™€ ORM ๋ชจ๋‘ Writer ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • Writer ๋Š” Chunk ๋‹จ์œ„์˜ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.
  • ๊ทธ๋ž˜์„œ DB ์˜ ์˜์†์„ฑ๊ณผ ๊ด€๋ จํ•ด์„œ ํ•ญ์ƒ ๋งˆ์ง€๋ง‰์— Flush๋ฅผ ํ•ด์ค˜์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ์˜์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” JPA, Hibernate ์˜ ๊ฒฝ์šฐ ItemWriter ๊ตฌํ˜„์ฒด์—์„œ๋Š” flush() ์™€ session.clear() ๊ฐ€ ๋”ฐ๋ผ์˜ต๋‹ˆ๋‹ค.

JpaItemWriter

@Override
public void write(List<? extends T> items) {
  EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory);
  if (entityManager == null) {
    throw new DataAccessResourceFailureException("Unable to obtain a transactional EntityManager");
  }
  doWrite(entityManager, items);
  entityManager.flush();
}

HibernateItemWriter

@Override
public void write(List<? extends T> items) {
  doWrite(sessionFactory, items);
  sessionFactory.getCurrentSession().flush();
  if (clearSession) {
    sessionFactory.getCurrentSession().clear();
  }
}

Writer ๊ฐ€ ๋ฐ›์€ ๋ชจ๋“  Item ์ด ์ฒ˜๋ฆฌ๋œ ํ›„, Spring Batch ๋Š” ํ˜„์žฌ ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.
DB ์™€ ๊ด€๋ จ๋œ Writer ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด 3๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • JdbcBatchItemWriter
  • HibernateItemWriter
  • JpaItemWriter

JdbcBatchItemWriter

  • ORM ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๋Œ€๋ถ€๋ถ„ JdbcBatchItemWriter ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • JDBC ์˜ Batch ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ํ•œ๋ฒˆ์— DB ๋กœ ์ „๋‹ฌํ•˜์—ฌ DB ๋‚ด๋ถ€์—์„œ ์ฟผ๋ฆฌ๋“ค์ด ์‹คํ–‰๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ์ด์œ ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ DB ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ํšŸ์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜์—ฌ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ๊พ€ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

    • ์—…๋ฐ์ดํŠธ๋ฅผ ์ผ๊ด„ ์ฒ˜๋ฆฌ๋กœ ๊ทธ๋ฃนํ™”ํ•˜๋ฉด DB ์™€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ„ ์™•๋ณต ํšŸ์ˆ˜๊ฐ€ ์ค„์–ด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.
  • JdbcBatchItemWriterJobConfiguration

์ถ”๊ฐ€๋กœ ์•Œ์•„๋‘ฌ์•ผํ•  ๋ฉ”์†Œ๋“œ afterPropertiesSet

  • ์ด ๋ฉ”์†Œ๋“œ๋Š” InitializingBean ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ๊ฐ–๊ณ  ์žˆ๋Š” ๋ฉ”์†Œ๋“œ์ž…๋‹ˆ๋‹ค.
  • JdbcBatchItemWriter, JpaItemWriter ๋“ฑ ItemWriter ์˜ ๊ตฌํ˜„์ฒด๋“ค์€ ๋ชจ๋‘ InitializingBean ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • ์—ฌ๊ธฐ์„œ afterPropertiesSet ๊ฐ€ ํ•˜๋Š” ์ผ์€ ๊ฐ๊ฐ์˜ Writer ๋“ค์ด ์‹คํ–‰๋˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ํ•„์ˆ˜๊ฐ’๋“ค์ด ์ œ๋Œ€๋กœ ์„ธํŒ…๋˜์–ด์žˆ๋Š”์ง€๋ฅผ ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค.
  • Writer ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์œ„ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ทธ ์•„๋ž˜์—์„œ ๋ฐ”๋กœ ์‹คํ–‰ํ•ด๋ณด๋ฉด ์–ด๋А ๊ฐ’์ด ๋ˆ„๋ฝ๋˜์—ˆ๋Š”์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JpaItemWriter

  • ์ด๋ฒˆ์— ์•Œ์•„๋ณผ Writer ๋Š” ORM ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” JpaItemWriter ์ž…๋‹ˆ๋‹ค.

  • JpaItemWriterJobConfiguration

CustomItemWriter

Reader ์™€ ๋‹ฌ๋ฆฌ Writer ์˜ ๊ฒฝ์šฐ Custom ํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ•  ์ผ์ด ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Reader ์—์„œ ์ฝ์–ด์˜จ ๋ฐ์ดํ„ฐ๋ฅผ RestTemplate ์œผ๋กœ ์™ธ๋ถ€ API ๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•  ๊ฒฝ์šฐ
  • ์ž„์‹œ ์ €์žฅ์„ ํ•˜๊ณ  ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•ด ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด์— ๊ฐ’์„ ๋„ฃ์–ด์•ผ ํ•  ๊ฒฝ์šฐ
  • ์—ฌ๋Ÿฌ Entity ๋ฅผ ๋™์‹œ์— save ํ•ด์•ผ ํ•  ๊ฒฝ์šฐ

์ด๋ ‡๊ฒŒ Spring Batch ์—์„œ ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜์ง€ ์•Š๋Š” Writer ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” ItemWriter ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

Releases

Packages

Contributors

Languages