์๋
ํ์ธ์.
์ ๋ ๋์ถ ๋ฐ ํฌ์ ์ฐ๊ณ ํ๋ซํผ์์ ๋ฐฑ์๋ ๊ฐ๋ฐ์๋ก ๊ทผ๋ฌด ์ค์ธ 2๋
์ฐจ ๊ฐ๋ฐ์ ์ ์ ์ผ์
๋๋ค.
์ด์ ์ค์ธ ํ์ฌ ์๋น์ค์์ ๋ด๋ถ์ ์ผ๋ก ๋ฐ์ดํฐ ์ ํฉ์ฑ์ ๊ฒ์ฆํ๋ ์ค, ํธ๋์ญ์ ์ฒ๋ฆฌ ์๊ฐ๊ณผ ๋ฐฐ์น ์์ ์ ๋นํจ์จ์ฑ์ผ๋ก ์ํ ๊ณ์ข ์๊ณ ์ ์๋น์ค ๋ด๋ถ ํฌ์ธํธ(Point)์ ๋ถ์ผ์น๋ก ์ธํด ์ ํฉ์ฑ ๊ฒ์ฆ ์์ ์ด ์คํจํ๊ฑฐ๋, ์๋ชป๋ ๋ ธํฐ๊ฐ ๋ฐ์ก๋๋ ๊ฒฝ์ฐ๊ฐ ์์์ต๋๋ค.
์ด ๊ธ์์๋ ๊ธฐ์กด์ Tasklet ๊ธฐ๋ฐ ๋ฐฐ์น ์ฒ๋ฆฌ ๋ฐฉ์์์ ๋ฐ์ํ ๋ฌธ์ ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด, Chunk ๊ธฐ๋ฐ ์ฒ๋ฆฌ์ Partitioning ๊ธฐ๋ฒ์ ๋์ ํ ๊ฒฝํ์ ๊ณต์ ํ๋ ค ํฉ๋๋ค.
์ ํฌ ํ์ฌ๋ ์จ๋ผ์ธํฌ์์ฐ๊ณ ๊ธ์ตํ๋ซํผ์
๋๋ค.
ํ์ฌ๋ ์์ ํ ์๊ธ์ด์ฉ์ ์ํด ์ ํ์ํ์ ํตํ ์์น๊ธ ์ ํ ์ด์ฉ์ ํ๊ณ ์์ต๋๋ค. ํ์ฌ์ ์๊ธ ํ๋ฆ์ ๊ฐ๋จํ ๋ค์ด์ด๊ทธ๋จ์ผ๋ก ๊ทธ๋ ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๋ฌผ๋ก ๋ค์ด์ด๊ทธ๋จ์ ๊ทธ๋ ค์ง ๊ฒ ์ธ์ ์๊ธ ํ๋ฆ์ด ์กด์ฌํ์ง๋ง ํ์ฌ ๋ฌธ์ ๋ฅผ ์ดํดํ๊ธฐ ์ํ ๋ถ๋ถ๊ณผ๋ ๋ฌด๊ดํ๋ ๋นผ๋๋ก ํ์ต๋๋ค.
๋ฌธ์ ๋ฅผ ์ดํดํ๊ธฐ ์ํด ์ ๊ทธ๋ฆผ์์ ๊ฐ์ฅ ์ค์ํ ๋ถ๋ถ์ ์ค์ ์๊ธ์ ์ ํ์ํ์์ ๊ด๋ฆฌ๋ฅผ ํด์ค๋ค๋ ์ ์ ๋๋ค.
ํฌ์์๊ฐ ๋ง์์ ์ ํ์ํ ๊ฐ์๊ณ์ข๋ก ์ ๊ธํ๋ค๋ฉด ์ค์ ์ ๊ธ๋ ๋ง์์ ์ ํ์ํ์์ ๊ด๋ฆฌํ๊ณ ๋ง์์ด ์ ๊ธ๋๋ค๋ ์ฌ์ค๋ง ์์ฌ๋ก ํต์ง๋๋ค๋ ๊ฒ ์ ๋๋ค.
์ ํฌ ์ญ์ ๋ด๋ถ์ ์ผ๋ก ์ ํ์ํ๊ณผ๋ ๋ณ๊ฐ๋ก ์ฌ์ฉ์์ ์๊ณ ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ ํฉ์ฑ์ ๊ฒ์ฆํ๊ณ ์์ต๋๋ค. ์ ํฌ๊ฐ ๊ด๋ฆฌํ๋ ์ฌ์ฉ์ ์๊ณ ๋ Point๋ผ ๋ช ๋ช ํ๊ณ ์์ต๋๋ค.
๊ธ์์๋ ๋ช ์นญ์ ๋ค์๊ณผ ๊ฐ์ด ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๊ณ์ข ์๊ณ ์ Point์ฌ์ด์ ๋ฐ์ดํฐ ์ ํฉ์ฑ์ด ๋ถ์ผ์นํ๋ ๊ฒฝ์ฐ๋ค์ด ์๊ธธ ์ ์์ต๋๋ค. ์๋ก๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ๋ค์ด ์์ ์ ์์ฃ .
ํฌ์์ A๊ฐ ์ ๊ธ์ ํ์ง๋ง ์ํ๊ณผ ์์ฌ ์๋น์ค๊ฐ ์ฌ์ด์ ์ ๊ธ ํต์ง ์ฌ์ด ๋ฌธ์ ๋ก Point์ ๋ฐ์์ด ๋์ง ์์์ ๋
์๋ฆฌ๊ธ ์ง๊ธ ์์ฒญ์ผ๋ก ์ ํ์ํ์์ ํฌ์์ ๊ฐ์๊ณ์ข๋ก ์ ๊ธ ์ฒ๋ฆฌ ํ์ผ๋ Point์๋ ๋ฐ์๋์ง ์์ ๊ฒฝ์ฐ
ํฌ์์๊ฐ ํฌ์ํ ์ดํ์ Point๋ ์ฐจ๊ฐํ์ผ๋ ์ค์ ๋์ถ์ ์คํ๋์ง ์์ ๊ณ์ข ์๊ณ ์์๋ ์ฐจ๊ฐ๋์ง ์์ ๊ฒฝ์ฐ
๋ฌผ๋ก ๋์ ๊ด๋ จ๋ ๊ต์ฅํ ๊ต์ฅํ ์ค์ํ ๋ฐ์ดํฐ์ด๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ ์ ํฉ์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์๋ง์ ๋ฐฉ์ด๋ก์ง๋ค์ด ์์ต๋๋ค. ๊ทธ๋ ๊ธฐ์ ์ ํฉ์ฑ์ด ๊นจ์ง๋ ๊ฒฝ์ฐ๋ ๊ต์ฅํ ๋๋ฌผ๋ค๊ณ ๋ง์ ๋๋ฆด ์ ์์ต๋๋ค.
์ ๊ฐ ๋ง์๋๋ฆฌ๊ณ ์ถ์๋ ๋ถ๋ถ์ ์ค์ ๊ณ์ข ์๊ณ ์ Point ์ฌ์ด์ ๊ฐ๊ทน์ด ์๊ธธ ์ ์๋ค๋ ๋ถ๋ถ์ ์ค๋ช
๋๋ฆฌ๊ณ ์ถ์์ต๋๋ค.
์ด๋ฐ ๋ฐฐ๊ฒฝ๋ถ๋ถ์ ์ค๋ช
๋๋ฆฌ๋ฉฐ ๋ฌธ์ ์ํฉ์ผ๋ก ๋์ด๊ฐ๋๋ก ํ๊ฒ ์ต๋๋ค.
์์์ ์ธ๊ธํ๋๋ก ๊ณ์ข ์๊ณ ์ Point๋ ๋๊ณผ ๊ด๋ จ๋ ๊ต์ฅํ ์ค์ํ ๋ฐ์ดํฐ์์ผ๋ก ์๋ง์ ๋ฐฉ์ด๋ก์ง ์ธ์๋ ๋ฐ์ดํฐ ๊ฒ์ฆ์ ์ํด ํ๋ฃจ์ ํ๋ฒ ์ฌ์ฉ์๋ถ๋ค์ ๊ณ์ข ์๊ณ ์ Point ๋ฐ์ดํฐ ์ฌ์ด์ ์ฐจ์ด๊ฐ ์กด์ฌํ๋์ง ์์น๊ธ์ ๋น๊ตํ๊ณ ๊ณ์ข ์์ก๊ณผ Point์ ์ฐจ์ด๊ฐ ์๋ค๋ฉด ํด๋น ๋ชฉ๋ก์ ์ ์ฅํ๊ณ ๊ด๋ฆฌ์์๊ฒ ๋ ธํฐํด์ฃผ๋ ๋ฐฐ์น๊ฐ ๋๊ณ ์์ต๋๋ค.
๊ธฐ์กด Tasklet ๋ฐฉ์์ผ๋ก ์๋ํ๋ ์์น๊ธ ๋น๊ต Job์
๋๋ค.
์ ๊ทธ๋ฆผ๋ง ๋ณด๋๋ผ๋ ๋ช๊ฐ์ง ๋ฌธ์ ์ ์ ์ธ๊ธํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
ํฌ์์๊ฐ ์๊ณ ๋ ์๋ก ์์กด์ฑ์ด ์๋๋ฐ๋ ๋๊ธฐ, ๋ธ๋กํน ๋ฐฉ์์ผ๋ก ์๋ํ๊ณ ์์ต๋๋ค. ์ด๋ก ์ธํด ํด๋น Job์ด ๊ฒฐ๊ณผ์ ์ผ๋ก Batch์ ๋ฆฌ์์ค๋ฅผ ํ์ ์ด์์ผ๋ก ๋ง์ด ์ก์๋จน๊ฒ ๋ฉ๋๋ค.
ํ step์์์ ์ฐจ์ก ๋น๊ต์ ๋น๊ต ๊ฒฐ๊ณผ์ ๋ํ ํธ๋ค๋ง์ ๋ชจ๋ ํ๊ณ ์์ต๋๋ค. ํ Step์์ ์ฑ ์์ด ์ฌ๋ฌ๊ฐ ์กด์ฌํ๊ฒ๋ผ ๊ฐ๋ ์ฑ ๋ฐ ์ ์ง๋ณด์์ฑ์ด ๋จ์ด์ง๊ฒ ๋ฉ๋๋ค.
์ ์ธ๊ธํ ๋ฌธ์ ์ ์ธ์ ๊ฐ์ฅ ์ค์ํ ํ๊ฐ์ง ๋ฌธ์ ์ ์ด ๋ ์กด์ฌํ๋๋ฐ ์ด ์ด์ ๋ฅผ ๊ทผ๊ฑฐ๋ก ๊ด๋ฆฌ์๋ถ์ ์ค๋ํ์ฌ ๋ฆฌํํ ๋ง์ ์งํํ ์ ์์์ต๋๋ค.
Tasklet์ด ํด๋น Step์ด ๋๋ ๋๊น์ง ํ Transaction์ผ๋ก ๋์ํ๊ธฐ๋๋ฌธ์ ์์น๊ธ ๋น๊ต๋์ค ๋ฐ์ดํฐ ์ ํฉ์ฑ์ด ๋ง์ง ์๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๋ฐ๋ก ์๋์ ๊ฐ์ ๊ฒฝ์ฐ์ธ๋ฐ์.
7์์ Transaction์ด ์์ํ๊ณ 7์ 10๋ถ์ฏค ์ ๊ธ ํต์ง๊ฐ ๋ฐ์ํ๋ค๋ฉด ํด๋น point๋ฅผ ์ฝ์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ์๊ฒผ์ต๋๋ค.
์ ํฌ๋ DB๋ก Mysql์ ์ฌ์ฉํ๊ณ ์์๊ณ Mysql์ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์์ค์ REPEATABLE READ
์ด๊ธฐ ๋๋ฌธ์ MVCC๋ก ๋์ํด transaction ์์ ์์ ์ ์ค๋
์ท์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๋ฒ๋ฆฐ ๊ฒ์ด์ฃ .
(๋น๊ต ๋ก์ง์๋ Point ๋ฟ๋ง ์๋ ์ฌ๋ฌ๊ฐ์ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ค๋ ํ์ํฉ๋๋ค. ex) ์ํ ์์ ๊ธ์ก, ํฌ์ ๋๊ธฐ ๊ธ์ก, ์ง๊ธ ์์ ๊ธ์ก ๋ฑ. ์์์์๋ Point๋ง ํ ์ด๋ธ๋ง ์์๋ก ๋ค์์ต๋๋ค. )
๋ถํ์ค ๋คํ์ผ๋ก๋ ๋ ธํฐ๋ฅผ ๋ฐ์๋ณด๋ ๊ด๋ฆฌ์๋ ๋ด๋ถ ์ฌ์ฉ์ (ํ์ฌ ์ง์๋ถ) ์ด์๊ธฐ ๋๋ฌธ์ ๋ ธํฐ๋ฅผ ๋ฐ์๋ณด๊ณ ๋ ๋ฐฑ์คํผ์ค์์ ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ๊ณ ๊ณ์ข ์๊ณ ์ ๋ฐ์ดํฐ ์ ํฉ์ฑ์ด ์๋ ๊ฒ์ ํ์ธํด์ฃผ์์ง๋ง ๊ด๋ฆฌ์ ์ ์ฅ์์๋ ๋ถํ์ํ ์ ๋ฌด๊ฐ ๋๋ ๊ฒ์ด๊ณ ๊ฐ๋ฐ์ ์ธ ๊ด์ ์์๋ ์๋ชป๋ ๋ฐ์ดํฐ๋ก ๋ ธํฐ๋ฅผ ๋ณด๋ด๋ ์ด๋ ์๋ชป๋ ๋ถ๋ถ์ด๋ผ ํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ธฐ์กด Tasklet ๋ฐฉ์์ผ๋ก ๊ตฌํ๋ ๋ฐฐ์น ์์ ์ ํ๋์ ํธ๋์ญ์ ๋ด์์ ๋ชจ๋ ์์ ์ด ์ฒ๋ฆฌ๋๋ค ๋ณด๋, ํธ๋์ญ์ ์ข ๋ฃ ์ ๊น์ง ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ํ์ง ๋ชปํ๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ํนํ 7์์ ๋ฐฐ์น ์์ ์ด ์์๋ ํ ์ ๊ธ ํต์ง๊ฐ 7์ 10๋ถ์ ๋ฐ์ํ๋ฉด ํด๋น ๋ฐ์ดํฐ๋ ๋ฐฐ์น ๊ฒฐ๊ณผ์ ๋ฐ์๋์ง ์๋ ์ํฉ์ด ๋ฐ์ํ์ต๋๋ค.
๋ฟ๋ง ์๋๋ผ ํ ํธ๋์ญ์ ๋ด์์ ๋น๊ต ์์ ๊ณผ ์๋ฆผ ์ฒ๋ฆฌ ๋ก์ง์ ๋ชจ๋ ์ํํ๋ค ๋ณด๋, ๋ฐฐ์น ์์ ์๊ฐ์ด ๊ธธ์ด์ง๊ณ ์คํจ ์ ์ฒ์๋ถํฐ ์ฌ์์ ํด์ผ ํ๋ ๊ตฌ์กฐ์ ๋ฌธ์ ๋ ์์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ค์ ์ธ ๊ฐ์ง๋ฅผ ๋ชฉํ๋ก ์ค์ ํ์ต๋๋ค.
ํธ๋์ญ์
๋จ์ ์ต์ํ
ํธ๋์ญ์
์ ๊ฐ๋ฅํ ์งง์ ๋จ์๋ก ๋ถ๋ฆฌํด ๋ฐ์ดํฐ ์ ํฉ์ฑ์ ๊ฐ์ .
์ฑ
์ ๋ถ๋ฆฌ
๋ฐ์ดํฐ ๊ฒ์ฆ๊ณผ ์๋ฆผ ์ฒ๋ฆฌ ๋ก์ง์ ๋ถ๋ฆฌํ์ฌ ์ฝ๋ ๊ฐ๋
์ฑ๊ณผ ์ ์ง๋ณด์์ฑ ํฅ์.
๋ณ๋ ฌ ์ฒ๋ฆฌ ๋์
๋ฐ์ดํฐ ๊ฐ ์์กด์ฑ์ด ์๋ ํน์ฑ์ ํ์ฉํด ์์
์๋๋ฅผ ์ต์ ํ.
Tasklet ๋ฐฉ์์์ Chunk ๋ฐฉ์์ผ๋ก ์ ํํ๋ฉฐ ๊ฐ์ฅ ํฐ ๋ณํ๋ ํธ๋์ญ์ ๋จ์๊ฐ ์์์ก๋ค๋ ์ ์ ๋๋ค. ๊ธฐ์กด์๋ ํ๋์ ํธ๋์ญ์ ์ด ์ ์ฒด ์์ ์ ์์ฐ๋ฅด๋ค ๋ณด๋ ์์ ์ค๊ฐ์ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๊ฐ ๋ฐ์๋์ง ์๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ์ด๋ฅผ Chunk๋ก ๋๋์ด ์ฒ๋ฆฌํ๋ฉฐ ๊ฐ Chunk๋ง๋ค ๋ ๋ฆฝ์ ์ผ๋ก ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๋๋ก ์ค๊ณํ์ต๋๋ค.
Chunk ๋ฐฉ์์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ ํธ๋์ญ์ ๋ฒ์๋ฅผ ์ ํํ ์ ์๋ค๋ ์ ์ ๋๋ค. ์ด๋ก ์ธํด ๋ฐฐ์น ์คํ ์ค์๋ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๊ฐ ๋ฐ์๋ ์ ์์๊ณ , ์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๋ ํน์ Chunk๋ง ์ฌ์ฒ๋ฆฌํ ์ ์๊ฒ ๋์์ต๋๋ค.
Chunk ๊ธฐ๋ฐ ์ฒ๋ฆฌ๋ก ๋ฐ์ดํฐ ์ ํฉ์ฑ์ ๊ฐ์ ํ์ง๋ง, ๊ฐ Chunk ์ฌ์ด์ฆ ๋ด์์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ธ๋กํน ๋ฐฉ์์ผ๋ก ๋์ํ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์๋ฒ ๋ฆฌ์์ค๋ฅผ ํ์ ์ด์์ผ๋ก ์ก์๋จน๋ ๋ฌธ์ ๋ ์ฌ์ ํ์ต๋๋ค.
ํฌ์์ ์๊ณ , Point ๋ฐ์ดํฐ๊ฐ์๋ ์์กด์ฑ์ด ์์ผ๋ฏ๋ก ๋ธ๋กํน ๋ฐฉ์์ผ๋ก ๋์ํ ํ์๋ ์์์ฃ .
์ด๋ฅผ ๋ณด์ํ๊ธฐ ์ํด Partitioning ๊ธฐ๋ฒ์ ์ ์ฉํ์ต๋๋ค. ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ๊ฐ์ Partition์ผ๋ก ๋๋ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๋ฉด์ ์๋๋ฅผ ๊ฐ์ ํ์ต๋๋ค.
PartitionHandler
๋ฅผ ํ์ฉํด ๊ด๋ฆฌ. Partitioning์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ์ ์๋ Partition ๋จ์๋ก ๋๋ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก๋ Partitioner
๊ฐ ๋ฐ์ดํฐ๋ฅผ GridSize์ ๋ฐ๋ผ ๋ฏธ๋ฆฌ ๋๋ ๊ฐ Partition์ ๋ถ๋ฐฐํ๊ณ , ๊ฐ Partition์ ์์ ์๊ฒ ํ ๋น๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
ํ์ง๋ง Partition์ ๋ฏธ๋ฆฌ ๊ณ ์ ํฌ๊ธฐ๋ก ๋๋๋ฉด, ๊ฐ ํํฐ์ ์ค๋ ๋ ๋ณ ์ข ๋ฃ ์๊ฐ์ด ํฌ๊ฒ ์์ดํจ์๋ ๋๊ณ ์๋ ์ค๋ ๋์์ ์ถ๊ฐ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ์ง ์์ผ๋ ์ด ์ฒ๋ฆฌ์๊ฐ์ ๋์ด๋๊ฒ ๋ฉ๋๋ค.
์ ํฌ ํ์์๋ ์ด๋ฐ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด ๋ชจ๋ ํํฐ์ ์ Reader๊ฐ ํ์ฌ ์กฐํ์ง์ ์ ์ค๋ ๋ ์ธ์ดํํ๋๋ก ๊ณต์ ํ๊ฒ ํด์ ๋จผ์ writer์ ์์ ๊น์ง ๋๋ธ ํํฐ์ ์ด ๋ค์์์ ์ ํ ๋น ๋ฐ์ ์ ์๋๋ก ๊ตฌํํ์์ต๋๋ค.
QuerydslPagingItemReader ๊ตฌํ ์ฝ๋ ์์
@Bean
@StepScope
public QuerydslPagingItemReader<BalanceCheckDto> querydslItemReader(
@Value("#{jobParameters['startDate']}") Date startDate,
@Value("#{jobParameters['endDate']}") Date endDate) {
return new QuerydslPagingItemReader<>(entityManagerFactory, DEFAULT_CHUNK_SIZE, queryFactory -> {
QBalanceCheck balanceCheck = QBalanceCheck.balanceCheck;
return queryFactory.selectFrom(balanceCheck)
.where(balanceCheck.createdDate.between(startDate, endDate))
.orderBy(balanceCheck.id.asc());
});
}
startDate
, endDate
: ๋ฐฐ์น ์คํ ์ ๋์ ์ผ๋ก ์ ๊ณต๋๋ ํ๋ผ๋ฏธํฐ.long currentExecutionOrder = executionOrder.getAndIncrement();
long startIndex = (currentExecutionOrder) * getPageSize();
int totalRecords = stepContext.getInt("totalRecords");
if (startIndex >= totalRecords) {
initResults(); // ๋น ๊ฒฐ๊ณผ๋ก ์ด๊ธฐํ
tx.commit();
return;
}
int chunkSizeToRead = Math.min(getPageSize(), (int) (totalRecords - startIndex)); // ๋จ์ ๋ฐ์ดํฐ ํฌ๊ธฐ๋งํผ ์ฝ๊ธฐ
// QueryDSL Query ์์ฑ
JPQLQuery<T> query = createQuery()
.offset(startIndex)
.limit(chunkSizeToRead);
์ QuerydslPagingItemReader๋ฅผ ์ ํํ๋๊ฐ?
๊ฐ์ ๋ ์
Querydsl ๊ธฐ๋ฐ Reader๋ฅผ ๋์ ํ๋ฉฐ Reader๊ฐ ๋์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ฉด์ ๋ ์ ์ฐํ๊ณ ํจ์จ์ ์ธ ๋ฐฐ์น ์์ ์ด ๊ฐ๋ฅํด์ก๋ค๊ณ ์๊ฐํฉ๋๋ค.
Step์ ๊ฐ ์ฑ ์์ ๋ง๊ฒ ๋ถ๋ฆฌํ์ฌ ์ ์ง๋ณด์์ฑ ๋ฐ ๊ฐ๋ ์ฑ์ ํฅ์์์ผฐ์ต๋๋ค. ๊ฐ Step์ ๋ค์๊ณผ ๊ฐ์ ์ฑ ์๋ค์ ๋งก๊ณ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ ํฌ๋ ํธ๋์ญ์ ์ ๋จ์๋ฅผ ์ต์ํํ๊ธฐ ์ํด Reader, Processor, Writer์ ํธ๋์ญ์ ์ ๊ฐ๊ฐ ๋ถ๋ฆฌํ์ฌ ๊ตฌํํ์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก๋ Reader, Processor, Writer๋ฅผ ์ฒญํฌ ๋จ์๋ก ํธ๋์ญ์ ์ ๋ฌถ์ด ์์ ํ๊ฒ ๋๋๋ฐ ์ ํฌ๋ ๊ณ์ข ์์ก์ด๋ผ๋ ๋ฐ์ดํฐ ์์ฒด๊ฐ ์ ํ์ํ์์ ๊ด๋ฆฌํ๋ค๋ณด๋ ์ฒญํฌ๋จ์๋ก Reader, Processor, Writer์ transaction์ ๋ฌถ๋๋ค ํ๋๋ผ๋ ์๋ฏธ๊ฐ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค.
1. ๋ฐ์ดํฐ ์ ํฉ์ฑ ๊ฐํ
ํธ๋์ญ์
๋จ์๋ฅผ ์ต์ํํ๋ฉด์ ๋ฐ์ดํฐ ์ ํฉ์ฑ ๋ฌธ์ ์ ํ๋ฅ ์ด ํ์ ํ๊ฒ ์ค์ด๋ค๊ฒ ๋์ต๋๋ค. ์์
์ค๊ฐ์ ๋ฐ์ํ ์
๊ธ ํต์ง๋ ๊ธฐํ ๋ณ๊ฒฝ์ฌํญ๋ ๊ฑฐ์ ์ค์๊ฐ์ผ๋ก ๋ฐ์ํ ์ ์๊ฒ ๋์์ต๋๋ค.
2. ์ฒ๋ฆฌ ์๋์ ๋ฆฌ์์ค ํจ์จ์ฑ
์ค๋ ๋ ๊ด๋ฆฌ์ ๋ณ๋ ฌ ์ฒ๋ฆฌ
๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด SimpleAsyncTaskExecutor
์ ThreadPoolTaskExecutor
๋ฅผ ๋น๊ต ํ
์คํธํ๋ฉฐ ์ต์ ์ ์ค์ ์ ์ฐพ์์ต๋๋ค. ์ค๋ ๋ ํ ํฌ๊ธฐ์ ๋ฐ๋ฅธ ์๋๋ฅผ ๋น๊ตํ์ฌ ์ ์ ํ ์ค๋ ๋ ๊ฐฏ์๋ฅผ ํ์ํ์ต๋๋ค.
์์ ๊ฐ์ ํ
์คํธ ๊ฒฐ๊ณผ gridSize ๋ฐ thread ๊ฐ์๋ 10์ผ๋ก ๊ณ ์ ํ์ต๋๋ค.
ํธ๋์ญ์
์ ์ปค๋ฐํ์ง ์๊ณ EntityManager๋ฅผ ๊ทธ๋ฅ closeํด๋ฒ๋ ธ์ ๋
ํ
์คํธํ๋ ๊ณผ์ ์์ Reader์์ transaction์ closeํ์ง ์๊ณ entityManager๋ฅผ closeํด๋ฒ๋ ธ์ ๋ HikariCP Deadlock ๋ฌธ์ ๋ฅผ ๋ง์ดํ๊ฒ ๋์ต๋๋ค. transaction์ entityManager๊ฐ close ๋์๋ commitํ๊ฒ ๊ฑฐ๋ ์๊ฐํ์๋๋ฐ ์๋์ฌ์ ๋นํฉํ์์ฃ . ์๊ฐํด๋ณด๋ฉด ๋น์ฐํ๊ฑด๋ฐ ๋ง์
๋๋ค.
ํด๋น ๋ฌธ์ ๋ transaction์ closeํ๊ณ entityManager๋ฅผ closeํ๋ฉด์ ํด๊ฒฐํ๊ฒ ๋ฉ๋๋ค.
Reader, Processor, Writer, Listener ๊ฐ ์ญํ ๋ถ๋ฆฌ
๋ก์ง ๋ถ๋ฆฌ ๊ณผ์ ์์ ๊ฐ์ฅ ๊ณ ๋ฏผ์ด ๋์๋ ๋ถ๋ถ์ค ํ๋๋ Processor์ Writer ๊ฐ์ ์ญํ ์ด ์ค์ฒฉ๋์ง ์๋๋ก ์ค๊ณํ๋ ๊ฒ์ด์์ต๋๋ค. ๋
ธํฐํด์ผํ ํ์ ๋ชฉ๋ก ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๋ค์ Step์ผ๋ก ์์ ํ๊ฒ ์ ๋ฌํ ์ง ๊ณ ๋ฏผํ ๋์ ConcurrentLinkedQueue
๋ฅผ ์ฌ์ฉํด ์ค๋ ๋ ์์ ํ ๋ฐ์ดํฐ ๊ณต์ ๋ฅผ ๊ตฌํํ์ต๋๋ค.
๋ํ ๊ตฌํ ์ด๊ธฐ์ initialize ์์ ์ด๋ ์ด๊ธฐํ ์์ ์ด Listener์ ๊ตฌํ์ด ๋์ด์์์ต๋๋ค. ํด๋น ๋ถ๋ถ์ด ํด๋์ค์ ์ญํ ๊ณผ ๋ง์ง ์์๊ธฐ ๋๋ฌธ์ ๋ณ๋์ Step์ผ๋ก ๋ถ๋ฆฌํ์ฌ ๊ตฌํํ์ต๋๋ค.
(ํด๋น ์ฝ๋ ๋ฆฌ๋ทฐํ์ ์คํฌ๋ผ์ ํตํด ๊ฐ์ ์ ์ ์กฐ์จํ๊ณ ์์ ํ์ต๋๋ค!)
์ ๋ก์๋ Chunk, Partitioning ๋์
์ ํตํ ๋ฌธ์ ํด๊ฒฐ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์ดํํ์ฌ ํ์ฅ๋์ ์ค๋ํ๋ ๊ณผ์ ๋ถํฐ๊ฐ ๋์ ์ด์์ต๋๋ค.
๋คํํ ํ์ฅ๋๋ํ ํ์์ฑ์ ๊ณต๊ฐํด์ฃผ์
จ๊ณ ์ ํฌ ํ์์ ๋งก์์ ์งํํ ์ ์์์ต๋๋ค.
์ด๋ฒ ๋ฆฌํฉํ ๋ง ํ๋ก์ ํธ๋ ๋จ์ํ ์์ธ ๋ฐ์ํ๋ฅ ์ ํ๋ฝ ๋ฐ ์ฑ๋ฅ์ ๊ฐ์ ํ๋ ๋ฐ ๊ทธ์น์ง ์๊ณ , ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ์ฌ์ ๋ฆฝํด ์ ์ง๋ณด์์ฑ๊ณผ ์ฌ์ฌ์ฉ์ฑ์ ํ๋ณดํ๋ค๋ ์ ์์ ์ค์ํ ๊ฒฝํ์ด ๋์์ต๋๋ค.
ํนํ Chunk์ Partitioning ๊ธฐ๋ฒ์ ์ฅ์ ์ ์ต๋ํ ํ์ฉํด ํจ์จ์ ์ธ ๋ฐฐ์น๋ฅผ ์ค๊ณํ ์ ์ ํฅํ ๋ค๋ฅธ ๋ฐฐ์น ์์ ์๋ ์ ์ฉํ ์ ์๋ ์ข์ ์ ๋ก๊ฐ ๋ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
์ฌ๋ฌ๊ฐ์ง ๊ฒฝํํ๋ฉฐ Spring Batch์ ๋ํ ์ดํด๋๋ ํฌ๊ฒ ๋์ผ ์ ์์๋ ์๊ฐ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ด๋ฒ ๋ฆฌํฉํ ๋ง์์ ์ ๋ ์ค์ ๊ตฌํ์ ๋ด๋นํ์ง ์์์ต๋๋ค. Chunk, Partitioning ๋์ ์ ์, ์ฐธ์ฌ ์ธ์ ๊ฒฐ์ , ์ผ์ ์กฐ์จ, ์คํฌ๋ผ ์งํ, ๋์ ๊ธฐ์ ๊ฒฐ์ , ์ฝ๋ ๋ฆฌ๋ทฐ ๋ฑ์ ๋ด๋นํ๊ณ ์ํคํ ์ณ ์ค๊ณ, ํธ๋ฌ๋ธ ์ํ , ๊ตฌํ๋ฐฉํฅ ์ค์ ๋ฑ์ ์ฐธ์ฌํ์ต๋๋ค.
๊ฐ์ฅ ์ค์ํ Chunk, Partitioning ๋ฐฉ์ ๊ตฌํ ๋ฐ ํ ์คํธ๋ฅผ ๋ด๋นํด์ฃผ์ ์ ํฌ ํ์ ํ์ฑ๋, ๋ณ์ฑ๋๊ป ๊ฐ์ฌ์ธ์ฌ๋๋ฆฌ๋ฉฐ ์ด๋ง๊ธ์ ๋ง์น๋๋ก ํ๊ฒ ์ต๋๋ค.
https://techblog.woowahan.com/2662/
https://jojoldu.tistory.com/336
https://jojoldu.tistory.com/339
https://docs.spring.io/spring-batch/reference/readersAndWriters.html