[Spring] JPA์˜ ํ”Œ๋Ÿฌ์‹œ(flush)

๋ฐ˜์‘ํ˜•

JPA๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์˜์†์‹œ์ผœ ์ปค๋ฐ‹ํ•˜๋Š” ๊ณผ์ •๊นŒ์ง€๋ฅผ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, JPA์˜ commit()์„ ํ˜ธ์ถœํ•  ๋•Œ ํ•ญ์ƒ ๋ฐœ์ƒํ•˜๋Š” flush()๋Š” ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š” ๋…€์„์ผ๊นŒ์š”?

 

 

flush()

์ปค๋ฐ‹ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด JPA ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์žˆ๋Š” ๊ฐ์ฒด๋“ค์ด DB๋กœ ๋ฐ˜์˜๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‹ค์ œ๋กœ commit() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ์ด๊ฒƒ์ด ์ง„ํ–‰๋˜๋Š” ๊ฒƒ์ผ๊นŒ์š”? ์‚ฌ์‹ค์€ commit() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ flush() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์–ด์ง€๊ณ , ์‹ค์ œ๋กœ๋Š” flush() ๋ฉ”์†Œ๋“œ์— ์˜ํ•ด์„œ DB์— ๋ฐ˜์˜๋˜์–ด์ง‘๋‹ˆ๋‹ค.

์ฆ‰, flush๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋‚ด์šฉ์„ DB์— ๋ฐ˜์˜ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๋ฉ”์†Œ๋“œ์ด๋ฉฐ, ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ์žˆ๋Š” SQL ์ฟผ๋ฆฌ๊ฐ€ DB ์„œ๋ฒ„๋กœ ๋ณด๋‚ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ๊ทธ๋Œ€๋กœ ๋‚จ์•„ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ˜๋“œ์‹œ ๊ฐ์ฒด๋ณ„๋กœ ์ค€์˜์†(detached)์ƒํƒœ๋กœ ์ „ํ™˜ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// EntityManager ์ƒ์„ฑ
EntityManager em = emf.createEntityManager();

// ์˜์† Entity ์กฐํšŒ
Cafe cafe = em.find(Cafe.class, 1);

// ์˜์† Entity ์ˆ˜์ •
cafe.setName("iceAmericano");

// ์ด ๋•Œ, DB ์„œ๋ฒ„๋กœ Query ์ „์†ก
em.flush();

์ดํ›„, commit() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ๋Š” DB์— ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋“ค์ด ๋ชจ๋‘ ์ €์žฅ๋˜์—ˆ์Œ์ด ํ™•์ •๋˜์–ด์ง€๊ฒŒ ๋˜๋ฏ€๋กœ ์ด ๋•Œ๋ถ€ํ„ฐ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋‚ด์šฉ๊ณผ 1์ฐจ ์บ์‹œ์— ์žˆ๋˜ ๊ฐ์ฒด๋“ค์ด ๋ชจ๋‘ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

 

 

flush() ๋™์ž‘ ๊ณผ์ •

commit์€ DB์˜ Transaction commit ์ฒ˜๋Ÿผ DB์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๋ฐ˜์˜์„ ํ™•์ •์ง€์—ˆ์„ ๋•Œ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฉ”์†Œ๋“œ์˜€๊ณ , ์‹ค์ œ ์ฟผ๋ฆฌ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋Š” ๋ณ„๊ฐœ๋กœ ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด flush ๋ฉ”์†Œ๋“œ๋Š” ์–ด๋–ค์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฑธ๊นŒ์š”?

  1. ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•œ๋‹ค. (Dirty Checking)
  2. ์ˆ˜์ •๋œ Entity๋ฅผ ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ๋“ฑ๋กํ•œ๋‹ค.
  3. ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์˜ Query๋ฅผ DB์— ์ „์†กํ•œ๋‹ค. (INSERT, UPDATE, DELETE ๋“ฑ์˜ DML)
  4. flush() ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ํ›„, commit() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ณต์Šตํ•œ๋‹ค๋ฉด, SELECT ์ฟผ๋ฆฌ์™€ ๊ฐ™์€ ์กฐํšŒ ์ฟผ๋ฆฌ๋Š” EntityManager์—์„œ ๋ฐ”๋กœ ์กฐํšŒํ•˜๊ณ , ์ˆ˜์ •์ด๋‚˜ ์ถ”๊ฐ€ ์‚ฌํ•ญ์— ๋Œ€ํ•ด์„œ๋งŒ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ๋„ฃ๊ณ , ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ๋„ฃ์—ˆ๋‹ค๊ฐ€ DB์— ๋ฐ˜์˜ํ•˜๋Š” ๋ฐฉ์‹์ด๋ž€ ์ ์„ ์•Œ์•„๋‘ก์‹œ๋‹ค.์ด๋Ÿฌํ•œ flush ๋ฉ”์†Œ๋“œ๊ฐ€ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋Š” DB Transaction์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. DB๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์“ธ ๋•Œ ์ž‘์—… ๋‹จ์œ„(Transaction)๋ฅผ ๋‘๊ณ  ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น Transaction์˜ ๋์ (commit) ์ง์ „์—๋งŒ ๋™๊ธฐํ™”๋ฅผ ํ•ด์ฃผ๋ฉด ๋˜๋ฏ€๋กœ ์ค‘๊ฐ„ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. JPA์—์„œ ๋ฐ์ดํ„ฐ์˜ ์‹ฑํฌ๋‚˜ ๋™์‹œ์„ฑ์— ๊ด€๋ จ๋œ ๊ฒƒ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์ด ์•„๋‹Œ DB์˜ Transaction์— ์œ„์ž„ํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ์ด๋Ÿฌํ•œ ์ด์Šˆ๋Š” ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์œผ์…”๋„ ๋ฉ๋‹ˆ๋‹ค.

 

 

flush()๋Š” ์–ธ์ œ ํ˜ธ์ถœ๋ ๊นŒ?

JPA์—์„œ flush ๋ฉ”์†Œ๋“œ๊ฐ€ commit() ์‹œ์ ์— ํ˜ธ์ถœ๋œ๋‹ค๋ผ๊ณ  ํ•œ๋‹ค๋ฉด, ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตณ์ด flush()๋ฅผ ๊ฐ•์ œ๋กœ ํ˜ธ์ถœํ•ด์•ผ ๋  ๋•Œ๋Š” ์–ธ์ œ์ผ๊นŒ์š”? ๋””๋ฒ„๊น…ํ•˜๊ฑฐ๋‚˜ ์ •๋ง๋กœ commit ์ง์ „์—, ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ต์„œ ๊ฐ•์ œ ํ˜ธ์ถœ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค๋ฉด, ์šฐ๋ฆฌ๊ฐ€ flush()๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์‹œ์ ์ด ์–ธ์ œ์ธ์ง€๋Š” ์•Œ์•„์•ผ๊ฒ ์ฃ ?

  • Transaction commit์‹œ ํ˜ธ์ถœ
  • JPQL ์ฟผ๋ฆฌ ์‹คํ–‰์‹œ ํ˜ธ์ถœ

๋ณดํ†ต JPA๋ฅผ ๊ธฐ๋ณธ ์˜ต์…˜์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์œ„์™€ ๊ฐ™์ด commit ํ•  ๋•Œ์™€ JPQL ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, flush ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. JPQL์ด๋ž€ Java Persistence Query Language์˜ ์•ฝ์ž๋กœ Java์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์ฟผ๋ฆฌ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. Java์— ๋งž์ถฐ SQL ์ฟผ๋ฆฌ๋ฅผ ์ถ”์ƒํ™” ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  DB์™€ ์—ฐ๋™๋˜์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—๋งŒ ์žˆ๋‹ค๊ฐ€ DB์—์„œ๋Š” ๋‹ค์‹œ SQL๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋˜๋Š” ์›๋ฆฌ์ž…๋‹ˆ๋‹ค.

// EntityManager ์ƒ์„ฑ
EntityManager em = emf.createEntityManager();

// ์ค‘๊ฐ„์— Query ์กฐํšŒ
query = em.createQuery("select c from Cafe c", Cafe.class);
List<Cafe> cafeMenus = query.getResultList();

Spring Data JPA์—์„œ๋Š” @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜์—ฌ JPQL์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜ JPA์—์„œ๋„ EntityManager ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ createQuery ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด JPQL์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ๋Š” DDL์ด๋“  DML์ด๋“  Query๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „, ์ž๋™์œผ๋กœ flush ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์™œ ์ž๋™์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๊ฑธ๊นŒ์š”? ๊ทธ๊ฒƒ์€ EntityManager์˜ ๊ธฐ๋ณธ flush ์˜ต์…˜์ด FlushModeType.AUTO๋กœ ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

em.setFlushMode(FlushModeType.COMMIT);

๋งŒ์•ฝ, ์ปค๋ฐ‹ํ•  ๋•Œ๋งŒ flush ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์œ„์™€ ๊ฐ™์ด EntityManager ๊ฐ์ฒด์˜ flushMode ํƒ€์ž…์„ COMMIT์œผ๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋‹ค์Œ๋ถ€ํ„ฐ JPQL์„ ์‚ฌ์šฉํ•  ๋• flush ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

JPQL์„ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ, flush ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋Š” ์–ธ์ œ์ผ๊นŒ์š”? ๋ฐ”๋กœ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์—†๋Š” ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•  ๋•Œ๋Š” flush ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์žˆ๋Š” ๋„๋ฉ”์ธ์— ์—†๋Š” ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•ด์•ผ ํ•  ๊ฒฝ์šฐ, ์˜์† ์ƒํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๋•Œ๋Š” JPQL์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ, flush ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ๋™๊ธฐํ™” ํ•œ๋‹ค๋ฉด, JPA์˜ ์ด์ ์„ ๊ทธ๋Œ€๋กœ ์‚ด๋ฆด ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ์ฃ .

 

๋งˆ์น˜๋ฉฐ...

์—ฌ๊ธฐ๊นŒ์ง€ ๊ฐ„๋‹จํ•˜๊ฒŒ flush ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค. ์—ฌํƒœ๊นŒ์ง€ commit ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ DB์— ๋ฐ˜์˜๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, flush ๋ฉ”์†Œ๋“œ๋ฅผ ๋ณด๊ฒŒ ๋˜๋ฉด์„œ JPA๊ฐ€ DB์™€ ์ •ํ™•ํ•˜๊ฒŒ ๋™๊ธฐํ™” ํ•  ์ˆ˜ ์žˆ๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ์•Œ๊ฒŒ ๋œ ๊ณ„๊ธฐ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments