๋ฌธ์ ์ํฉ: ์๋ก ๋ค๋ฅธ ํธ๋์ญ์ ์์ ์ํฐํฐ ๋ณ๊ฒฝ ์ ๋ณ๊ฒฝ๊ฐ์ง๊ฐ ์๋ํ๋๊ฐ?
์ธ๋ถ API ํธ์ถ์ ํธ๋์ญ์
์์ ๋ถ๋ฆฌํ๊ธฐ ์ํด FACADE ํจํด์ ๋์
ํ์ต๋๋ค.
3๊ฐ์ ์๋น์ค๋ฅผ ๋ฆฌํฉํ ๋งํ๋ฉฐ, ํธ๋์ญ์
๋ฒ์ ๋ฐ์์ ์ธ๋ถ API๋ฅผ ํธ์ถํ๋๋ก ์ค๊ณํ์๊ณ , ์ฝ๋ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์์ต๋๋ค.
// ํธ๋์ญ์
์์ ์ธ๋ถ API ํธ์ถ์ ๋ถ๋ฆฌํ๊ณ ์ ๋ง๋ Facade ๊ฐ์ฒด
public class Facade {
private final Service1 service1;
private final Service2 service2;
public ... createSomething(...) {
// 1๋ฒ ์๋น์ค ํธ๋์ญ์
์์
EntityA entityA = service1.doSomething(...);
// ์ธ๋ถ API ํธ์ถ (ํธ๋์ญ์
์ธ๋ถ)
externalApi.call();
// 1๋ฒ ์๋น์ค์ ๋ฐํ๊ฐ์ 2๋ฒ ์๋น์ค์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ
service2.processSomething(entityA);
}
}
์ฌ๊ธฐ์ ๋ฌธ์ ๋ 1๋ฒ ์๋น์ค์ ๋ฐํ๊ฐ์ธ entityA๋ฅผ 2๋ฒ ์๋น์ค์์ ๋ณ๊ฒฝํ ๋, ๋ณ๊ฒฝ๊ฐ์ง(dirty checking)๊ฐ ์ ์ฉ๋๋์ง ์ฌ๋ถ์์ต๋๋ค. ์ฆ, ์๋ก ๋ค๋ฅธ ์๋น์ค์ ํธ๋์ญ์ ์์ ์์์ฑ ์ปจํ ์คํธ์ ๋ณ๊ฒฝ๊ฐ์ง๋ฅผ ํ์ฉํ ์ ์๋๊ฐ์ ๋ํ ํ์ธ์ด์์ต๋๋ค.
ํด๊ฒฐ ๊ณผ์ : ์์์ฑ ์ปจํ ์คํธ์ ํธ๋์ญ์ ์ ๊ด๊ณ ์ดํด
์ด๋ฅผ ํ์ธํ๊ธฐ ์ํด์๋ ์์์ฑ ์ปจํ ์คํธ์ ์คํ๋ง์ ํธ๋์ญ์ ์ด ์ด๋ค ์ํธ์์ฉ์ ํ๋์ง ์์์ผ ํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก JPA์ ์์์ฑ ์ปจํ ์คํธ๋ ํธ๋์ญ์ ๋ง๋ค ์๋ก ์์ฑ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด, A์๋น์ค์์ ํธ๋์ญ์ ์ ์์ํ๊ณ , B์๋น์ค์ ํธ๋์ญ์ ์ด ์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ํธ๋์ญ์ ์ ํ ์ต์ ์ด REQUIRES_NEW๋ก ์ค์ ๋์ด ์๋ค๊ณ ๊ฐ์ ์ ํ๋ค๋ฉด,
- A์๋น์ค์ ํธ๋์ญ์ ์ด ์์๋๋ฉฐ A๋ง์ ์์์ฑ ์ปจํ ์คํธ๊ฐ ์์ฑ๋ฉ๋๋ค.
- B์๋น์ค ํธ์ถ ์, ์ ํ ์ต์ ์ด REQUIRES_NEW์ด๋ฏ๋ก B์์ ์๋ก์ด ํธ๋์ญ์ ์ด ์์๋๋ฉฐ B๋ง์ ์์์ฑ ์ปจํ ์คํธ๊ฐ ์์ฑ๋ฉ๋๋ค.
- B์๋น์ค๋ A์๋น์ค์ ์ ํ ๋ค๋ฅธ ํธ๋์ญ์ ๋ฐ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
* ์ถ์ฒ: ์์์ฑ ์ปจํ ์คํธ์ ํธ๋์ญ์ propagation
๋ฐ๋ผ์ FACADE ๊ณ์ธต์ ์ฝ๋์์ 1๋ฒ ์๋น์ค์ ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๊ณ , 2๋ฒ ์๋น์ค์ ํธ๋์ญ์ ์ ์์ํ๊ฒ ๋๋ฉฐ ์ด๋ ์๋ก ๋ค๋ฅธ ํธ๋์ญ์ ์ ๋๋ค. ์ฆ, ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ณต์ ํ์ง ์๊ฒ ๋ ๊ฒ์ด๋ผ๊ณ ์์ํ ์ ์์ต๋๋ค.
ํ์ง๋ง, ๊ฐ๊ณผํ ์ : OSIV ์ค์ ์ฌ๋ถ
ํ์ง๋ง, ๊ฐ๊ณผํ ๊ฒ์ด ์์ผ๋ OSIV ์ค์ ์ฌ๋ถ์ ๋๋ค.
OSIV ๋ ์์์ฑ ์ปจํ ์คํธ ๋ฒ์ ๋ด์์๋ ์ง์ฐ ๋ก๋ฉ์ ํ๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก ์์์ฑ ์ปจํ ์คํธ์ ์๋ช ๋ฒ์๋ฅผ ํธ๋์ญ์ ๋ฒ์ ๋ฐ์์๋ ์ ์ง์์ผ์ ์ํฐํฐ๋ฅผ ์ค์์ ์ํ๊ฐ ์๋ ์์์ํ๋ก ์ ์งํ๊ฒ ํ๋ ๊ฒ์ ๋๋ค.
์คํ๋ง ๋ถํธ์์ JPA๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ๊ธฐ๋ณธ์ ์ผ๋ก OSIV๊ฐ ํ์ฑํ๋์ด ์์ผ๋ฉฐ ์๋ฒ๋ฅผ ์คํํ ๋, WARN ๋ก๊ทธ๋ฅผ ํตํด ํ์ฑํ ์ฌ๋ถ๋ฅผ ์ ์ ์์ต๋๋ค.
WARN JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
์ฆ, OSIV ํ์ฑํ์ ์ํด ์์์ฑ ์ปจํ ์คํธ์ ์์กด ๋ฒ์๋ ์๋ ์ฌ์ง์ฒ๋ผ HTTP ์์ฒญ์ด ๋ค์ด์ค๊ณ ๋๊ฐ๋ ๊น์ง ์์กด ๋ฒ์๊ฐ ๋์ด๋๊ฒ ๋ฉ๋๋ค.
๊น์ํ๋์ ์๋ฐ ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ ์ฑ ์ ๋ฐ๋ฅด๋ฉด ์์์ฑ ์ปจํ ์คํธ์ ์์กด ๋ฒ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ์๋ธ๋ฆฟ ํํฐ๋, ์คํ๋ง ์ธํฐ์
ํฐ์์ ์์์ฑ ์ปจํ
์คํธ๋ฅผ ์์ฑํ๋ค. ๋จ ํธ๋์ญ์
์ ์์ํ์ง ์๋๋ค
- ํธ๋์ญ์ ์ด ์์ํ์ง ์๊ธฐ ๋๋ฌธ์ DB์ปค๋ฅ์ ์ ์์ง ํ๋ํ์ง ์์ต๋๋ค. DB์ปค๋ฅ์ ๊ณผ ๊ฐ์ ๋ฆฌ์์ค๋ ํธ๋์ญ์ ๋๊ธฐํ ๋งค๋์ (TransactionSynchronizationManager) ๊ฐ ์ป์ต๋๋ค.
- ์๋น์ค ๊ณ์ธต์์ @Transactional๋ก ํธ๋์ญ์ ์ ์์ํ ๋ 1๋ฒ์์ ๋ฏธ๋ฆฌ ์์ฑํด๋ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ฐพ์์์ ํธ๋์ญ์ ์ ์์ํ๋ค.
- ์๋น์ค ๊ณ์ธต์ด ๋๋๋ฉด ํธ๋์ญ์ ์ ์ปค๋ฐํ๊ณ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ํ๋ฌ์ํ๋ค. ์ด๋ ํธ๋์ญ์ ์ ๋๋ด์ง๋ง ์์์ฑ ์ปจํ ์คํธ๋ ์ข ๋ฃํ์ง ์๋๋ค.
- ์ปจํธ๋กค๋ฌ์ ๋ทฐ๊น์ง ์์์ฑ ์ปจํ ์คํธ๊ฐ ์ ์ง๋๋ฏ๋ก ์กฐํํ ์ํฐํฐ๋ ์์ ์ํ๋ฅผ ์ ์งํ๋ค.
- ์๋ธ๋ฆฟ ํํฐ๋, ์คํ๋ง ์ธํฐ์ ํฐ๋ก ์์ฒญ์ด ๋์์ค๋ฉด ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ข ๋ฃํ๋ค. ์ด๋ ํ๋ฌ์๋ฅผ ํธ์ถํ์ง ์๊ณ ๋ฐ๋ก์ข ๋ฃํ๋ค.
๊ทธ๋์, spring.jpa.open-in-view: false ์ค์ ์ ํตํด OSIV ๊ธฐ๋ฅ์ ๋์ง ์์๋ค๋ฉด OSIV ํ์ฑํ์ ์ํด 1๋ฒ ์๋น์ค์ 2๋ฒ ์๋น์ค๋ ๊ฐ์ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ณต์ ํ๊ฒ ๋๋ฉฐ 1๋ฒ ์๋น์ค์ ๋ฐํ๊ฐ์ธ ์ํฐํฐ A๋ 2๋ฒ ์๋น์ค์์ ๋ณ๊ฒฝ๊ฐ์ง๋ฅผ ์ฌ์ฉํ ์ ์์ ๊ฒ์ ๋๋ค.
OSIV ๋จ์ : DB ์ปค๋ฅ์ ๋ฏธ ๋ฐ๋ฉ
๊ทธ๋ฌ๋, ์ด๋ ์ฌ๊ธฐ์ ์ณ์ง ๋ชปํ ์ ํ์ ๋๋ค.
OSIV ํ์ฑํ๋ก ์ธํด ์์์ฑ ์ปจํ ์คํธ ๋ฒ์๊ฐ ๋์ด๋ฌ๋ค๋ ๊ฒ์ ํธ๋์ญ์ ์ ์์ํ๋ฉฐ ์ป์ DB ์ปค๋ฅ์ ์ HTTP ์์ฒญ์ด ๋๋ ๋๊น์ง ๋ฐ๋ฉํ์ง ์๊ฒ ๋ฉ๋๋ค.
์ฆ, [1๋ฒ ์๋น์ค ํธ๋์ญ์ ์์]๊ณผ [2๋ฒ ์๋น์ค ํธ๋์ญ์ ์์] ์ฌ์ด์ ์๋ ์ธ๋ถ API ํธ์ถํ ๋๋ DB ์ปค๋ฅ์ ์ ์ ์งํ๊ฒ ๋ฉ๋๋ค.
์ด๋ ์ธ๋ถ API ํธ์ถ์ ํธ๋์ญ์ ์์ ๋ถ๋ฆฌํ๊ธฐ ์ํด FACADE ํจํด์ ๋์ ํด์ ์ธ๋ถ API ํธ์ถํ๋ ๋์์ DB์ปค๋ฅ์ ์ ๋ฐ๋ฉํ๊ณ ํธ๋์ญ์ ์ ์งง๊ฒ ์ ์งํ๊ธฐ ์ํ ๋ชฉ์ ์ด์์ง๋ง, ์ ์ OSIV ํ์ฑํ๋ก ์ธํด ์ธ๋ถ API ํธ์ถ๋์ DB์ปค๋ฅ์ ์ด ๋ฐํ๋์ง ์๋ ๊ผด์ด ๋ฉ๋๋ค.
๊ฒฐ๋ก : OSIV ๋นํ์ฑํ ๋ฐ ์ฝ๋ ์์
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ yml ํ์ผ์ spring.jpa.open-in-view: false ์ค์ ์ ์ฃผ์ด OSIV ์ค์ ์ ๋๋๋ก ํ๊ฒ ์ต๋๋ค.
์๋ ๊ถ๊ธํ๋ '๋ฐํ๊ฐ A๊ฐ ์๋ก ๋ค๋ฅธ ์๋น์ค์ ํธ๋์ญ์ ์์ ๋ณ๊ฒฝ๊ฐ์ง๋ฅผ ์ฌ์ฉํ ์ ์๋๊ฐ?' ์ ๋ํ ๋ต์
- OSIV๊ฐ ํ์ฑํ๋ ๊ฒฝ์ฐ: 1๋ฒ ์๋น์ค(ํธ๋์ญ์
)์ 2๋ฒ ์๋น์ค(ํธ๋์ญ์
)์์ ์ํฐํฐ๋ฅผ ๊ณต์ ํด์ ๋ณ๊ฒฝ๊ฐ์ง๋ฅผ ์ฌ์ฉํ ์ ์์.
- ๋ณ๊ฒฝ๊ฐ์ง๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋ ์๋น์ค์ ํธ๋์ญ์ ์ด ๊ผญ ์์ด์ผ๋ง ํฉ๋๋ค. ํธ๋์ญ์ ์ด ์์ด์ผ ์์์ฑ ์ปจํ ์คํธ์ ๋ด์ฉ์ DB๋ก flush ํ๊ธฐ ๋๋ฌธ
- OSIV๊ฐ ๋นํ์ฑํ๋ ๊ฒฝ์ฐ: ์๋ก ๋ค๋ฅธ ํธ๋์ญ์ ์์ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ณต์ ํ์ง ์์ผ๋ฏ๋ก ๋ณ๊ฒฝ๊ฐ์ง๋ฅผ ์ฌ์ฉํ ์ ์์
ํ์ง๋ง, ์ธ๋ถ API ํธ์ถ์ ํธ๋์ญ์ ์์ ๋ถ๋ฆฌํ๊ธฐ ์ํด FACADE ํจํด์ ๋์ ํ๋ค๋ฉด, OSIV ์ ํ์ฑํ ์ฌ๋ถ๋ฅผ ๊ณ ๋ คํด์ DB์ปค๋ฅ์ ์ด ๋ฐ๋ฉ์ด ์ฌ๋ฐ๋ฅด๊ฒ ๋๋์ง ๋น์ฆ๋์ค ๋ก์ง์ ๊ฒํ ํ ํ์๊ฐ ์๊ฒ ์ต๋๋ค. ์ ๋ํ, OSIV ํ์ฑํ ์ฌ๋ถ๋ฅผ ๋๊ณ , ๋ณ๊ฒฝ๊ฐ์ง๋ฅผ ์ด์ฉํ์ง ์๋ ๋ฐฉ์์ผ๋ก ์ฝ๋๋ฅผ ์์ ํ๊ฒ ๋์์ต๋๋ค.
๋ง์น๋ฉฐ
์ฌ์ค ์ด ๊ณผ์ ์์ ๋ค๋ฃฌ OSIV ์ค์ ๊ณผ ์์์ฑ ์ปจํ ์คํธ์ ์๋ช ์ฃผ๊ธฐ๋, ์ด์ ์ JPA ๊ฐ์๋ฅผ ๋ค์ผ๋ฉฐ ์ด๋ฏธ ํ์ตํ๋ ๋ด์ฉ์ด์์ต๋๋ค. ํ์ง๋ง, ๊ฐ์๋ฅผ ๋ค์ ๋น์์๋ ๋จ์ํ ๋์ผ๋ก ๋ณด๊ณ ๋จธ๋ฆฌ๋ก ์ดํดํ ๊ฒ์ ๊ทธ์ณค๊ณ , ์๊ฐ์ด ์ง๋๋ ๊ทธ ๋ด์ฉ์ด ์ ํํ ๊ธฐ์ต๋์ง ์์์ต๋๋ค. ์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ํตํด ์ค์ค๋ก ๊ณ ๋ฏผํ๊ณ ํด๊ฒฐํ๋ ๊ณผ์ ์์ ์ง์์ ์ฒดํํ ์ ์์์ต๋๋ค.
๋ฌผ๋ก , OSIV ๋ฅผ ๊ณ ๋ คํด์ผ ํ๋ค๋ ์ ์ ๊ฐ์๋ฅผ ๋ฏธ๋ฆฌ ๋ฃ์ง ์์๋ค๋ฉด ๋ ๋ฆ๊ฒ ๊นจ๋ฌ์์์ง๋ ๋ชจ๋ฆ ๋๋ค. ํ์ง๋ง ์ด๋ฒ ๊ฒฝํ์ ํตํด ์ค์ค๋ก ์๊ฐํ๊ณ ์ง์์ ํ์ฉํ ๋, ๊ฐ์ฅ ์๋ฏธ ์๋ ํ์ต์ ํ ์ ์์์ ๋ค์ ํ๋ฒ ๋๋ผ๋ฉฐ ๋ง๋ฌด๋ฆฌ ํ๊ฒ ์ต๋๋ค.
์ฐธ๊ณ
- '์๋ฐ ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ' ์ฑ
- F lab: ์คํ๋ง ๋ถํธ์์์ OSIV(Open Session In View) ํจํด ์ดํด์ ์ ์ฉ