1. ๋ฌธ์ ์ํฉ
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ธฐ์ค์ผ๋ก ItemReader์ ๊ตฌํ์ฒด๋ฅผ ๋๋ ๋, Cursor Based ItemReader๊ณผ Paging Based ItemReader์ผ๋ก ๋๋ ์ ์๋ค.
Cursor ๊ธฐ๋ฐ์ ItemReader์ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์ ์ ์ง์์ ์ผ๋ก ๋ ์ ์ผ๋ก ์ฌ์ฉํ์ฌ ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋๋ ์์ ๊น์ง ์ปค๋ฅ์ ์ ๋์์ฃผ์ง ์๊ธฐ ๋๋ฌธ์, ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์ฑ๋ฅ์์ ์ํฅ์ ์ค ์ ์๋ค.
๋ฐ๋ผ์ Paging ๊ธฐ๋ฐ์ ItemReader๋ฅผ ์ ํํ๊ณ ์ต๊ทผ์ ์ค์ผ์ค๋ฌ์, ๋ฐฐ์น ๋ก์ง์ ๊ฐ๋ฐํ๋ค.
ํ์ง๋ง ์ค์ ๋ก์ง ์ํ ๊ฒฐ๊ณผ๋ ์ํ๋๋ฐ๋ก ๋์ง ์์๊ณ , ๋ช ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฑด๋๋ด์ฑ๋ก ์ํ๋์๋ค.
๋์ ๋ฐฐ์น ๋ก์ง์ ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด PENDING ์ค์ด๋ Apply๋ฅผ CANCELED๋ก ๋ณ๊ฒฝํด์ฃผ๋ ๊ฒ์ด๋ค. ์ฌ์ง์์ work_date_id๊ฐ 1์ธ ๋ฐ์ดํฐ๋ ์ ๋ถ CANCELED๋ก ๋ณ๊ฒฝ๋์ผ ํ์ง๋ง 4๊ฐ์ ๋ฐ์ดํฐ ์ค 2๊ฐ๋ง ๋ฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
2. ์์ธ
์์ธ์ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ ๋๋ฌธ์ด๋ค.
๋ง์ฝ ์๋์ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฐ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์กฐํ๋ ๊ฒ์ด๋ค.
SELECT * FROM Pay
WHERE successStatus = false
offset 0 limit 10
์ด ์กฐํ๋ ๋ฐ์ดํฐ๋ฅผ Update ํด๋ณด์.
์ฌ๊ธฐ์ ์ค์ํ ๊ฒ์ ์กฐํํ ๋ฐ์ดํฐ๋ฅผ Updateํ ๋ ๋ณ๊ฒฝ๋ ํ๋๊ฐ ์กฐํํ ๋ ์กฐ๊ฑด์ ์ฌ์ฉ๋๋ ๊ฒ์ด๋ค.
์ด Update๋ก ์ธํด์ ์ด์ ํ
์ด๋ธ์๋ false์ธ ๋ฐ์ดํฐ๊ฐ 40๊ฐ๋ง ์กด์ฌํ๋ค.
์ด ์ํ์์ ๋ค์ Paging ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น??
SELECT * FROM Pay
WHERE successStatus = false
offset 11 limit 10
์กฐํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.
40๊ฐ ๋ฐ์ดํฐ์์ 11๋ฒ์งธ ๋ถํฐ์ธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ฒ ๋๋ค.
์์ ์คํ๋ ์ฟผ๋ฆฌ์์ ๋์์ Updateํ์ฌ ์ ์ธ๋์ด ์ค์ ๋ก 21๋ฒ์งธ์ธ ๋ฐ์ดํฐ๊ฐ 11๋ฒ์งธ ๋ฐ์ดํฐ๋ก ์กฐํ๊ฐ ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ค๋ณด๋ 11๋ฒ์งธ ๋ฐ์ดํฐ๋ถํฐ 20๋ฒ์งธ๊น์ง ๋ฐ์ดํฐ๊ฐ ์กฐํ๋์ง ์๋๋ค.
3. ํด๊ฒฐ ๋ฐฉ์
1. Cursor ์ด์ฉ
๊ฐ์ฅ ๊ฐ๋จํ ํด๊ฒฐ ๋ฐฉ์์ cursor ๊ธฐ๋ฐ read ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ด๋ค.
Cursor๋ ํ๋ฒ ์ปค๋ฅ์ ์ ๋งบ๊ณ Database Cursor๋ฅผ ์ฎ๊ธฐ๋ ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์ ์์ ์กฐํํ๋ ๊ฒฐ๊ณผ๊ฐ ๋ฐ๋๋ค๊ณ ๋ค์ ์กฐํ์ ์ํฅ์ ๋ฏธ์น์ง ์๋๋ค.
Paging ๊ธฐ๋ฐ์ ์ด์ ์ ์ด๋ฆฌ๋ฉด์ ์กฐํํ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ๋ฐฉ๋ฒ์ ์์๊น??
PagingReader ์ค๋ฒ๋ผ์ด๋ฉ์ ํตํด ํด๊ฒฐํ ์ ์๋ค.
2. PagingReader ์ปค์คํ
Update๋ ๋๋ง๋ค ๋์ ๋ฐ์ดํฐ ๋ฒ์๊ฐ ์ค์ด๋๋, ์ผ๋ถ๋ฌ Page ๋ฒํธ๋ฅผ ๊ณ์ ๋ณ๊ฒฝ์ํค์ง ์๊ณ 0๋ฒ์งธ๋ก ๊ณ ์ ์ํค๋ ๊ฒ์ด๋ค.
@Bean
public ItemReader<Apply> applyReader() {
LocalDate tomorrow = LocalDate.now().plusDays(1);
JpaPagingItemReader<Apply> reader = new JpaPagingItemReader<>() {
@Override
public int getPage() {
return 0;
}
};
reader.setName("applyReader");
reader.setPageSize(1);
reader.setEntityManagerFactory(entityManagerFactory);
reader.setQueryString("select a from Apply a join fetch a.workDate w join fetch a.member m join fetch a.workDate.jobPost j where w.workDate <= :tomorrow and a.status = 'PENDING'");
Map<String, Object> parameters = new HashMap<>();
parameters.put("tomorrow", tomorrow);
reader.setParameterValues(parameters);
return reader;
}
๋ชจ๋ ์ฟผ๋ฆฌ์์ ์๋ ์ฌ์ง๊ณผ ๊ฐ์ด offset์ด 0์ผ๋ก ๊ณ ์ ๋๊ณ ๊ฑด๋ ๋ฐ๋ ํ์ ์์ด ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์ ์์ ์ผ๋ก ๋ฐ๋๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค.
4. ๊ฒฐ๋ก
DB Connection ์๊ฐ๊ณผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณ ๋ คํ์ ๋๋ Paging ๋ฐฉ๋ฒ์ด ๋ ์ข๋ค. ๋ฌผ๋ก ์๋ฒ๊ฐ Connection ์๊ฐ๊ณผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐ์ณ์ค ์ ์๋ค๋ฉด Cursor๋ฐฉ์์ด ๋ ๊ฐํธํ๊ณ ๋น ๋ฅด๊ณ ์ข์ ๊ฒ ๊ฐ๋ค.
๋ค๋ง, Paging์ ์ ํํ ๊ฒฝ์ฐ ์ ๋ ฌ, ๋๋ฝ ๋ฐ์ดํฐ ๋ฑ์ ์ ๊ฒฝ์ฐ๋ฉด์ ๊ฐ๋ฐํด์ผ ํ๋ค.