๊ด€๋ฆฌ ๋ฉ”๋‰ด

Welcome! Everything is fine.

[STUDY] Spring Batch ํ•ต์‹ฌ ๊ตฌ์กฐ์™€ ๊ฐœ๋… ์ •๋ฆฌ ๋ณธ๋ฌธ

์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

[STUDY] Spring Batch ํ•ต์‹ฌ ๊ตฌ์กฐ์™€ ๊ฐœ๋… ์ •๋ฆฌ

๊ฐœ๋ฐœ๊ณฐ๋ฐœ 2025. 6. 12.
728x90

๐Ÿง Spring Batch๋ž€?

๋ฐฐ์น˜(Batch) ์ฒ˜๋ฆฌ๋ž€ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ •ํ•ด์ง„ ์‹œ์ ์— ์ž๋™์œผ๋กœ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

  • ์˜ˆ์‹œ 
    • ๋งค์ผ ์ž์ • ์ฃผ๋ฌธ ๋ฐ์ดํ„ฐ ํ†ต๊ณ„ ์ €์žฅ
    • ๋งค์ฃผ ๊ณ ๊ฐ ๋Œ€์ƒ ์ด๋ฉ”์ผ ๋ฐœ์†ก
    • DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜, ์ •์‚ฐ ์ฒ˜๋ฆฌ ๋“ฑ
  • ํŠน์ง•
    • ์‚ฌ๋žŒ์ด ์ง์ ‘ ์š”์ฒญํ•˜์ง€ ์•Š์•„๋„ ์ž๋™์œผ๋กœ ์ฃผ๊ธฐ์  ์‹คํ–‰
    • ์‹ค์‹œ๊ฐ„์„ฑ๋ณด๋‹ค ์ •ํ™•์„ฑ๊ณผ ์•ˆ์ •์„ฑ์ด ์ค‘์š”
    • ์‹คํŒจ ์‹œ ์žฌ์ฒ˜๋ฆฌ, ๋กœ๊ทธ ์ถ”์ ์ด ์ค‘์š”

Spring Batch๋Š” ๋Œ€์šฉ๋Ÿ‰ ๋ฐฐ์น˜ ์ž‘์—…์„ ์‰ฝ๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” Spring ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ๋‹ค.

  • Job/Step ๊ธฐ๋ฐ˜ ๊ตฌ์„ฑ ์ œ๊ณต
  • ์˜ˆ์™ธ, ๋กœ๊ทธ. ์žฌ์‹œ์ž‘, ๋กœ๊น… ๋“ฑ์˜ ๊ธฐ๋Šฅ ์ œ๊ณต
  • ์ฒญํฌ ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ, ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๋“ฑ ๋‚ด์žฅ

๐Ÿ’ก Spring Batch์˜ ๊ตฌ์กฐ

Job๊ณผ Step

์•„๋ž˜ ๊ทธ๋ฆผ์€ Spring Batch์˜ ์ „๋ฐ˜์ ์ธ ์‹คํ–‰ ํ๋ฆ„์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

  • JobLauncher : ๋ฐฐ์น˜ ์‹คํ–‰์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ. ๋ฐฐ์น˜ ์‹คํ–‰ ์‹œ JobRepository์— JobExecution์„ ์ƒ์„ฑํ•ด ๊ธฐ๋ก
  • Job : ํ•˜๋‚˜์˜ ๋ฐฐ์น˜ ๋‹จ์œ„. ์—ฌ๋Ÿฌ Step์œผ๋กœ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ์Œ
  • Step : ์‹ค์ œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ๋‹จ์œ„. ๋‚ด๋ถ€์ ์œผ๋กœ Reader → Processor → Writer ์ˆœ์„œ๋กœ ์ฒ˜๋ฆฌ๋จ
  • JobRepository : Job/Step์˜ ์‹คํ–‰ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋ฉฐ, ์žฌ์‹œ์ž‘/์ค‘๋‹จ/์„ฑ๊ณต ์—ฌ๋ถ€ ๋“ฑ์„ ์ถ”์ 
  • ItemReader : ๋ฐ์ดํ„ฐ ์†Œ์Šค๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ (CSV, DB, API ๋“ฑ)
  • ItemProcessor : ์ฝ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณต, ๋ณ€ํ™˜, ํ•„ํ„ฐ๋ง
  • ItemWriter : ์ตœ์ข… ๋ฐ์ดํ„ฐ๋ฅผ ์™ธ๋ถ€๋กœ ์ถœ๋ ฅ (DB ์ €์žฅ, ํŒŒ์ผ ๊ธฐ๋ก ๋“ฑ)
๐Ÿ—ฃ๏ธ Spring Batch์˜ Job๊ณผ Step์˜ ๊ตฌ์กฐ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.
Spring Batch๋Š” Job๊ณผ Step์ด๋ผ๋Š” ์‹คํ–‰ ๋‹จ์œ„๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Job์€ ๋ฐฐ์น˜ ์ž‘์—…์˜ ์ „์ฒด ๋‹จ์œ„๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ์—ฌ๋Ÿฌ ๊ฐœ์˜ Step์œผ๋กœ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ Step์€ Reader, Processor, Writer ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํฌํ•จํ•˜๋ฉฐ ์‹ค์ œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ๋‹จ์œ„์ž…๋‹ˆ๋‹ค. Job์„ ์‹คํ–‰ํ•˜๋ฉด JobLauncher๊ฐ€ ์‹คํ–‰์„ ์‹œ์ž‘ํ•˜๊ณ , JobRepository์— ์‹คํ–‰ ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜์–ด ์ƒํƒœ ์ถ”์ ์ด๋‚˜ ์žฌ์‹œ์ž‘์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค. Step์€ ๊ฐ๊ฐ ๋…๋ฆฝ์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ณ , ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋ถ„๊ธฐํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋Š” ์ž‘์—…์„ ๋‹จ๊ณ„๋ณ„๋กœ ๋‚˜๋ˆ„๊ณ  ์‹คํ–‰ ํ๋ฆ„๊ณผ ์ƒํƒœ๋ฅผ ๋ช…ํ™•ํžˆ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค.
ํŠนํžˆ ์‹คํ–‰ ์‹คํŒจ ์‹œ ํŠน์ • Step๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ์ง€์›ํ•ด, ๋ณต๊ตฌ ๊ฐ€๋Šฅ์„ฑ๊ณผ ์‹คํ–‰ ์ œ์–ด๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

Reader · Processor  ·  Writer

Spring Batch์—์„œ ํ•˜๋‚˜์˜ Step์€ ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

๊ฐ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ , ๊ฐ€๊ณตํ•˜๊ณ , ์ €์žฅํ•˜๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๋ฉฐ, ์ฑ…์ž„์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋‹ค.

  • Reader (ItemReader) – ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๊ตฌ์„ฑ ์š”์†Œ
    • ์™ธ๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๋Š” ์—ญํ• 
    • ์ž…๋ ฅ ์†Œ์Šค๋Š” CSV, DB, XML, API ๋“ฑ ๋‹ค์–‘ํ•˜๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ
    • ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜, ๋” ์ด์ƒ ์ฝ์„ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด null ๋ฐ˜ํ™˜
  • Processor (ItemProcessor) – ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ
    • Reader์—์„œ ์ฝ์–ด์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•˜๋Š” ์—ญํ• 
    • ๋ฐ˜ํ™˜๊ฐ’์ด null์ผ ๊ฒฝ์šฐ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋Š” writer์— ์ „๋‹ฌ๋˜์ง€ ์•Š์Œ
    • ํ•„์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์•„๋‹ˆ๋ฉฐ, ํ•„์š” ์‹œ์—๋งŒ ์‚ฌ์šฉ
  • Writer (ItemWriter) – ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ
    • ์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ข…์ ์œผ๋กœ ์–ด๋–ค ํ˜•ํƒœ๋กœ ์ €์žฅํ• ์ง€ ์ •ํ•˜๊ณ , ์™ธ๋ถ€์— ์ถœ๋ ฅํ•˜๋Š” ์—ญํ• 
    • DB์— ์ €์žฅํ•˜๊ฑฐ๋‚˜, ํŒŒ์ผ๋กœ ์ถœ๋ ฅํ•˜๊ฑฐ๋‚˜, ์™ธ๋ถ€ API๋กœ ์ „์†กํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰
    • Reader์™€ ๋‹ฌ๋ฆฌ ์ฒญํฌ ๋‹จ์œ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ์ฒ˜๋ฆฌ

 

์•„๋ž˜ ์ฝ”๋“œ๋Š” ํŒ€ ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ๋œ ์ •์‚ฐ ์ฒ˜๋ฆฌ Step์˜ ์˜ˆ์‹œ๋‹ค. Settlement ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ , ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•œ ๋’ค DB์— ๋ฐ˜์˜ํ•˜๋Š” ๋‹จ์ผ Step์œผ๋กœ, chunk(100)์œผ๋กœ ์„ค์ •๋œ ๋งŒํผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ์•„ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๊ณ  ์ปค๋ฐ‹ํ•œ๋‹ค.

 

Step์€ Reader → Processor → Writer ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์œผ๋ฉฐ, ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ญํ• ์„ ํ•œ๋‹ค.

  • Reader : status๊ฐ€ 'READY'์ธ ์ •์‚ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒ(์ปค์„œ ๊ธฐ๋ฐ˜)
  • Processor : ์ƒํƒœ๋ฅผ 'COMPLETED'๋กœ ๋ณ€๊ฒฝ
  • Writer : ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ DB์— ๋ฐ˜์˜ (UPDATE)

 

Spring Batch๋Š” ์ฒญํฌ ๋‹จ์œ„๋กœ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํ•˜๋‚˜์˜ ์ฒญํฌ๊ฐ€ ์‹คํŒจํ•˜๋ฉด ํ•ด๋‹น ์ฒญํฌ๋งŒ ๋กค๋ฐฑ๋˜๊ณ , Job์€ ์ค‘๋‹จ๋˜๊ฑฐ๋‚˜ ์žฌ์‹œ์ž‘๋œ๋‹ค.

์ปค์„œ ๊ธฐ๋ฐ˜ vs ํŽ˜์ด์ง• ๊ธฐ๋ฐ˜ Reader

Spring Batch์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ฌ ๋•Œ๋Š” Reader ์ „๋žต์„ ์‹ ์ค‘ํ•˜๊ฒŒ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.
๋Œ€ํ‘œ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ์‹์€ ์ปค์„œ ๊ธฐ๋ฐ˜(Cursor-based) ๊ณผ ํŽ˜์ด์ง• ๊ธฐ๋ฐ˜(Paging-based) ๋‘ ๊ฐ€์ง€๋‹ค.
๋‘ ๋ฐฉ์‹ ๋ชจ๋‘ ๋Œ€๋Ÿ‰ ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ๋˜์ง€๋งŒ, ๊ธฐ์ˆ  ์Šคํƒ๊ณผ ๋ฐ์ดํ„ฐ ํŠน์„ฑ, ํŠธ๋žœ์žญ์…˜ ์ „๋žต์— ๋”ฐ๋ผ ์ ํ•ฉํ•œ ์ƒํ™ฉ์ด ๋‹ค๋ฅด๋‹ค.

 

์‹ค๋ฌด์—์„œ๋Š” ๋ณดํ†ต...

  • ์ปค์„œ ๊ธฐ๋ฐ˜์€ JdbcCursorItemReader์™€ ๊ฐ™์€ JDBC ๊ธฐ๋ฐ˜ ๋ฐฉ์‹
  • ํŽ˜์ด์ง• ๊ธฐ๋ฐ˜์€ JpaPagingItemReader์™€ ๊ฐ™์€ JPA ๊ธฐ๋ฐ˜ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋œ๋‹ค.

์•„๋ž˜๋Š” ๋‘ ๋ฐฉ์‹์˜ ์ฐจ์ด๋ฅผ ์ •๋ฆฌํ•œ ํ‘œ๋‹ค.

ํ•ญ๋ชฉ ์ปค์„œ ๊ธฐ๋ฐ˜(Cursor-based) ํŽ˜์ด์ง• ๊ธฐ๋ฐ˜(Paging-based)
์ฒ˜๋ฆฌ ๋ฐฉ์‹ ์ปค์„œ๋ฅผ ์—ด๊ณ  ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฝ์Œ ์ผ์ • ํฌ๊ธฐ๋กœ ๋‚˜๋ˆ„์–ด ๋ฐ˜๋ณต ์ฟผ๋ฆฌ๋กœ ์ฝ์Œ
์ฟผ๋ฆฌ ์‹คํ–‰ 1๋ฒˆ ์‹คํ–‰ ํ›„ ์ปค์„œ ์œ ์ง€ ์—ฌ๋Ÿฌ ๋ฒˆ ์ฟผ๋ฆฌ ์‹คํ–‰(page ์ˆ˜๋งŒํผ)
๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€๋‹ด ๋งŽ์Œ ๋งค ํŽ˜์ด์ง€๋งˆ๋‹ค ์ž‘๊ฒŒ ๋‚˜๋ˆ„์–ด ๊ฐ€์ ธ์™€ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€๋‹ด ์ ์Œ
์†๋„ ์ปค๋„ฅ์…˜ ์œ ์ง€๋กœ ์†๋„ ๋น ๋ฆ„ ๋‹ค์ˆ˜์˜ ์ฟผ๋ฆฌ๋กœ ์ธํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆผ
๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ์ฒ˜๋ฆฌ ์ค‘ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์—†์Œ ์ฒ˜๋ฆฌ ์ค‘ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์‹œ ์ค‘๋ณต/๋ˆ„๋ฝ ๊ฐ€๋Šฅ์„ฑ ์กด์žฌ
ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ ํŠธ๋žœ์žญ์…˜ ์ „์ฒด ์œ ์ง€ ๊ฐ ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ ํŠธ๋žœ์žญ์…˜ ๋ถ„๋ฆฌ ๊ฐ€๋Šฅ
์ปค๋„ฅ์…˜ ์ ์œ  ์ „์ฒด ์ž‘์—… ๋™์•ˆ ์ปค๋„ฅ์…˜ ์ ์œ  ๊ฐ ํŽ˜์ด์ง€๋งˆ๋‹ค ์ปค๋„ฅ์…˜ ์—ฐ๊ฒฐ/ํ•ด์ œ ๊ฐ€๋Šฅ
์ ํ•ฉํ•œ ์ƒํ™ฉ ์ •์ ์ธ ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ, ๋น ๋ฅธ ์ผ๊ด„ ์ฒ˜๋ฆฌ ๋ณ€๋™ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ, ๋ณ‘๋ ฌ์„ฑ/๋ณต์›๋ ฅ ํ•„์š” ์‹œ

 

JPA ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง•์€ ์—”ํ‹ฐํ‹ฐ ๊ด€๋ฆฌ์™€ ์—ฐ๊ด€ ๊ด€๊ณ„ ์ฒ˜๋ฆฌ ๋“ฑ ORM์˜ ์ด์ ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ๋Š” ์„ฑ๋Šฅ ์ €ํ•˜๋‚˜ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€๋‹ด์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ฉด, ์ปค์„œ ๊ธฐ๋ฐ˜์€ ResultSet์„ ์—ด์–ด ํ•œ ์ค„์”ฉ ๋ฐ์ดํ„ฐ๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์ด ํšจ์œจ์ ์ด๊ณ  ์ฒ˜๋ฆฌ ์†๋„๋„ ๋น ๋ฅด๋‹ค. ํ•˜์ง€๋งŒ ์ปค๋„ฅ์…˜์„ ์˜ค๋ž˜ ์ ์œ ํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ, ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋‚˜ ์žฌ์‹œ์ž‘์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ์ œ์•ฝ์ด ํฌ๋‹ค. ๊ฒฐ๊ตญ, ์–ด๋–ค ๋ฐฉ์‹์ด ๋” ๋‚ซ๋‹ค๊ณ  ๋‹จ์ •ํ•˜๊ธฐ๋ณด๋‹ค๋Š” ๋ฐฐ์น˜ ์žก์˜ ํŠน์„ฑ๊ณผ ์‹œ์Šคํ…œ ๊ตฌ์กฐ์— ๋งž๊ฒŒ ์ „๋žต์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

์ฒญํฌ(Chunk) ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ

  • ์ฒญํฌ(Chunk) : ์ผ์ •ํ•œ ๊ฐœ์ˆ˜๋กœ ๋ฌถ์ธ ๋ฐ์ดํ„ฐ ๋‹จ์œ„.
  • ์ฒญํฌ ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ ๋ฐฉ์‹ : ์ง€์ •ํ•œ ๊ฐœ์ˆ˜๋งŒํผ ๋ชจ์•„์„œ(์ฒญํฌ ๋‹จ์œ„๋กœ) ์ฒ˜๋ฆฌํ•˜๊ณ  ํ•œ ๋ฒˆ์— ์ปค๋ฐ‹ํ•˜๋Š” ๋ฐฉ์‹. ์ฒญํฌ ๋‹จ์œ„๋กœ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๋ถ€ํ•˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๋ฉด์„œ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ  ์‹คํŒจ ์‹œ ๋กค๋ฐฑ์„ ํšจ๊ณผ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ.

Spring Batch์—์„œ๋Š” chunk(10)์ฒ˜๋Ÿผ ์ฒญํฌ ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•ด ์„ค์ •ํ•˜๋ฉฐ, ๊ฐ ์ฒญํฌ๋Š” ๋‹ค์Œ ์ˆœ์„œ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค.

  1. ItemReader๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์”ฉ ์ฝ๋Š”๋‹ค.
  2. ์ง€์ •๋œ ์ฒญํฌ ํฌ๊ธฐ๋งŒํผ ๋ชจ์€๋‹ค.
  3. ItemProcessor๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•œ๋‹ค.
  4. ItemWriter๊ฐ€ ๊ฐ€๊ณต๋œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ์ €์žฅํ•˜๊ณ  ์ปค๋ฐ‹ํ•œ๋‹ค.
๐Ÿ—ฃ๏ธ Spring Batch์˜ Chunk์™€ Chunk ๊ธฐ๋ฐ˜ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”.
Spring Batch๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Chunk ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Chunk๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ผ์ • ๊ฐœ์ˆ˜๋กœ ๋ฌถ์€ ๋‹จ์œ„์ด๋ฉฐ, ์ด ๋‹จ์œ„๋กœ ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด chunk ํฌ๊ธฐ๋ฅผ 100์œผ๋กœ ์„ค์ •ํ•˜๋ฉด, ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๊ฑด์”ฉ ์ฝ๊ณ  ๊ฐ€๊ณตํ•˜๋˜ 100๊ฑด์ด ๋ชจ์ผ ๋•Œ๊นŒ์ง€๋Š” ์ปค๋ฐ‹ํ•˜์ง€ ์•Š๊ณ , 100๊ฑด์ด ์Œ“์ธ ์‹œ์ ์— ํ•œ ๋ฒˆ์— ์ €์žฅํ•˜๊ณ  ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ ๋งค ๊ฑด๋งˆ๋‹ค ์ปค๋ฐ‹ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋žœ์žญ์…˜ ๋ถ€ํ•˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ณ , ์ค‘๊ฐ„์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์ฒญํฌ ๋‹จ์œ„๋กœ๋งŒ ๋กค๋ฐฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ „์ฒด ์ž‘์—…์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. Chunk ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ๋Š” ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๋ฅผ ์ ์ ˆํžˆ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ๋„ ์‹คํŒจ ๋ณต๊ตฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์‹คํ–‰ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ฉฑ๋“ฑ์„ฑ (Idempotency)

  • ๋ฉฑ๋“ฑ์„ฑ(Idempotency) : ๊ฐ™์€ ์ž‘์—…์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์ˆ˜ํ–‰ํ•ด๋„ ๊ฒฐ๊ณผ๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ์„ฑ์งˆ.
  • Spring Batch์ฒ˜๋Ÿผ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒญํฌ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , ์ค‘๊ฐ„ ์‹คํŒจ ์‹œ ์žฌ์‹œ์ž‘์ด ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ์—์„œ๋Š” ๋ฉฑ๋“ฑ์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์ด ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ๊ณผ ์•ˆ์ •์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ํ•ต์‹ฌ ์š”์†Œ๊ฐ€ ๋œ๋‹ค.

๋ฉฑ๋“ฑ์„ฑ์ด ๋ณด์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด?

  • DB์— ์ค‘๋ณต๋œ ๋ ˆ์ฝ”๋“œ๊ฐ€ insert๋จ(DB์— ๋ณ„๋„์˜ Unique ์ œ์•ฝ์กฐ๊ฑด์ด ์—†๋Š” ๊ฒฝ์šฐ)
  • ์ด๋ฏธ ์ฒ˜๋ฆฌ๋œ ์ƒํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๋ฎ์–ด์”€
  • ์™ธ๋ถ€ ์‹œ์Šคํ…œ(API, ๋ฉ”์‹œ์ง€ ํ ๋“ฑ)์— ์ค‘๋ณต ์š”์ฒญ์ด ๋ฐœ์ƒํ•จ

์‹ค์ œ๋กœ๋Š” ItemWriter ๋‹จ๊ณ„์—์„œ์˜ ๋ฉฑ๋“ฑ์„ฑ ๋ณด์žฅ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค. Writer๋Š” ํŠธ๋žœ์žญ์…˜์˜ ์ปค๋ฐ‹ ์ง€์ ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๋‹จ๊ณ„์—์„œ์˜ ์ค‘๋ณต/๋ถˆ์ผ์น˜๋Š” ๊ณง ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ๋ฌธ์ œ๋กœ ์ง๊ฒฐ๋œ๋‹ค. Writer๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Reader์™€ Processor์—์„œ๋„ ๋ฐฉ์–ด์ ์œผ๋กœ ๋ฉฑ๋“ฑ์„ฑ์„ ๊ณ ๋ คํ•ด๋‘๋ฉด ๋” ์•ˆ์ •์ ์ธ ์„ค๊ณ„๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์•„๋ž˜๋Š” SettlementRegisterJobConfig ํด๋ž˜์Šค์˜ ์ผ๋ถ€์ด๋‹ค.

Reader์™€ Writer ๊ฐ ๋‹จ๊ณ„์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฉฑ๋“ฑ์„ฑ์ด ๋ณด์žฅ๋œ๋‹ค.

  • Reader : ์ด๋ฏธ settlement๊ฐ€ ์กด์žฌํ•˜๋Š” payment๋Š” ์กฐํšŒ๋˜์ง€ ์•Š์Œ
  • Writer : ๋ณ„๋„์˜ ์ค‘๋ณต ์ฒ˜๋ฆฌ ๋กœ์ง ์—†์ด๋„ ์•ˆ์ „ํ•˜๊ฒŒ INSERT ๊ฐ€๋Šฅ

๐Ÿ—ฃ๏ธ Spring Batch์—์„œ ๋ฉฑ๋“ฑ์„ฑ์€ ์–ด๋–ป๊ฒŒ ๋ณด์žฅํ–ˆ๋‚˜์š”?
Spring Batch๋Š” ์ฒญํฌ ๋‹จ์œ„๋กœ ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Step ๋„์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์žฌ์‹œ์ž‘๋˜๋Š” ๊ฒฝ์šฐ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ค‘๋ณต ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฉฑ๋“ฑ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด Reader ๋‹จ๊ณ„์—์„œ๋ถ€ํ„ฐ ์ค‘๋ณต ๊ฐ€๋Šฅ์„ฑ์„ ์ฐจ๋‹จํ•˜๋Š” ์กฐ๊ฑด์„ ๋ช…ํ™•ํžˆ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ •์‚ฐ ๋“ฑ๋ก Job์—์„œ๋Š” payment ํ…Œ์ด๋ธ”์—์„œ ์ƒํƒœ๊ฐ€ 'DONE'์ด๋ฉด์„œ, ์ด๋ฏธ settlement์— ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ๊ฑด๋งŒ ์กฐํšŒํ•˜๋„๋ก LEFT JOIN + IS NULL ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•ด ์ฒ˜๋ฆฌ ๋Œ€์ƒ์„ ์„ ๋ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ •์‚ฐ ์™„๋ฃŒ Job์—์„œ๋Š” settlement ํ…Œ์ด๋ธ”์—์„œ status๊ฐ€ 'READY'์ธ ๊ฑด๋งŒ ์กฐํšŒํ•ด ์ƒํƒœ๋ฅผ 'COMPLETED'๋กœ ์—…๋ฐ์ดํŠธํ•˜ ํ•˜๋„๋ก ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ Reader์—์„œ ์ค‘๋ณต ๋Œ€์ƒ์„ ์ œ๊ฑฐํ•˜๊ณ , Writer๋Š” ID ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์ด๋ฏธ ์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ๋‹ค์‹œ ์ปค๋ฐ‹๋˜์ง€ ์•Š๋„๋ก ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋•๋ถ„์— Job์ด ์žฌ์‹œ์ž‘๋˜๋”๋ผ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ์ค‘๋ณต ์ €์žฅ๋˜๊ฑฐ๋‚˜ ์ƒํƒœ๊ฐ€ ๋ฐ˜๋ณต ๋ณ€๊ฒฝ๋˜๋Š” ๋ฌธ์ œ ์—†์ด, ๋ฉฑ๋“ฑ์„ฑ์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ณด์žฅ๋˜๋Š” ๊ตฌ์กฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.