[Spring] OSIV๋ก ์์๋ณด๋ Spring Transaction ํค์ง๊ธฐ
Spring boot์๋ spring.jpa.open-in-view๋ผ๊ณ ํ๋ ์ต์ ์ด ์์ต๋๋ค. ์ด ์ต์ ์ JPA์ OSIV ๊ธฐ๋ฅ์ ON/OFF ํ ์ ์๋ ์ต์ ์ธ๋ฐ์.
์ด ์ต์ ์ด ๋ฌด์์ธ์ง ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
OSIV
๋จผ์ ์ด ์ต์ ์ JPA์ OSIV ๊ธฐ๋ฅ์ ์ฌ์ฉ ์ ๋ฌด๋ฅผ ๋ํ๋ด๋๋ฐ, OSIV๋, ์์์ฑ ์ปจํ ์คํธ๋ฅผ View๊น์ง ์ด์ด๋๋ ๊ธฐ๋ฅ์ ๋๋ค. ์์์ฑ ์ปจํ ์คํธ๊ฐ ๋ฌด์์ธ์ง ์ ๋ชจ๋ฅด์๊ฒ ๋ค๋ฉด ์๋ ๊ธ์ ์ฐธ๊ณ ํด๋ณด์ธ์.
2020.06.23 - [Programming/Spring] - [Spring] JPA์ ์์์ฑ ์ปจํ ์คํธ์ ์๋ช ์ฃผ๊ธฐ
OSIV๋ ์์์ฑ ์ปจํ ์คํธ๊ฐ ๊ณ์ ์ ์ง๋๋ฉด Entity ๊ฐ์ฒด๋ ์์ ์ํ๋ก ์ ์ง๋๋ ๊ธฐ๋ฅ์ผ๋ก์จ ์ด ๊ธฐ๋ฅ์ ์ฐจํ ๊ด๊ณํ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ์ง์ฐ ๋ก๋ฉํ ๋ ์ฌ์ฉํฉ๋๋ค.
OSIV ๋์ ์๋ฆฌ
๊ทธ๋ ๋ค๋ฉด Spring Framework ์์์ OSIV๋ ์ด๋ป๊ฒ ๋์ํ ๊น์? Spring์ด ์ ๊ณตํ๋ OSIV์๋ ๋ ๊ฐ์ง ์ฌ์ฉ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
- JPA OSIV Servlet Filter: org.springframework.orm.jpa.support.OpenEntityManagerViewFilter
- JPA OEIV Spring Interceptor: org.springframework.orm.jpa.support.OpenEntityManagerViewInterceptor
์์๋ค์ํผ ์์์ฑ ์ปจํ ์คํธ๋ ์ฌ์ฉ์๊ฐ ์์ฒญํ๋ ์์ ์์ ์์ฑ๋์ง๋ง ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๋ DB ํธ๋์ญ์ ์ ๋น์ฆ๋์ค ๊ณ์ธต์์๋ง ์ฌ์ฉํ ์ ์๋๋ก ํธ๋์ญ์ ์ด ๋ฐ์ํฉ๋๋ค.
Spring JPA์ OSIV ์ต์ ์ true๋ก ์ฃผ๊ฒ ๋๋ฉด ์์ ๊ฐ์ ๊ทธ๋ฆผ์ผ๋ก ๋์ํฉ๋๋ค. ์ด ์๋ฆฌ๋ฅผ ์์ฝํ๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
- Browser์ผ๋ก๋ถํฐ ์์ฒญ์ด ๋ค์ด์ค๋ฉด Servlet Filter๋ Spring Interceptor์์ ์์์ฑ ์ปจํ
์คํธ(EntityManager)๋ฅผ ์์ฑํฉ๋๋ค.
(ํ์ง๋ง ์ฐ๋ฆฌ๋ ์ด์ ๊ธ์์ ๋ค๋ค๋ฏ, ์ด ๋ถ๋ถ์์ Transaction์ ์์ํ๋ ๊ฒ์ ์๋๋๋ค.) - Transaction AOP ํน์ begin์ ์ด์ฉํด์ ํธ๋์ญ์
์ ์์ํ ๋ ์์์ ์์ฑํ ์์์ฑ ์ปจํ
์คํธ๋ฅผ ์ด์ฉํด ํธ๋์ญ์
์ ์์ํฉ๋๋ค.
(Spring boot์ ๊ฒฝ์ฐ๋ ์ด๋ฏธ ์ ์๋ autoconfigure๋ฅผ ์ด์ฉํฉ๋๋ค) - ์ ๊ทธ๋ฆผ์์๋ Service ํด๋์ค์์ Transaction AOP๋ฅผ ์ด์ฉํ ๊ฒฝ์ฐ์ด๋ฏ๋ก Service ๋ก์ง์ด ์๋ฃ๋๋ฉด ํธ๋์ญ์
์ ์ปค๋ฐํ๊ณ , ํธ๋์ญ์
์ ์ข
๋ฃ๋์ง๋ง ์์์ฑ ์ปจํ
์คํธ๋ ์์ง ์ด์์์ต๋๋ค.
(์ฆ, DB์ ์ปค๋ฅ์ ์ด ์์ง ์ข ๋ฃ๋ ์ํ๊ฐ ์๋๋๋ค.) - Controller์ View๊น์ง ์์์ฑ ์ปจํ ์คํธ๊ฐ ์ ์ง๋๊ธฐ ๋๋ฌธ์ ์ด ๋ ์ฌ์ฉํ Entity๋ ๊ณ์ ์์ ์ํ๋ฅผ ์ ์งํ๊ฒ ๋ฉ๋๋ค.
- Servlet Filter ํน์ Spring Interceptor๋ก ๋ก์ง์ด ๋ค์ ํ๊ท๋ ๊ฒฝ์ฐ, ๊ทธ ๋ ์์์ฑ ์ปจํ
์คํธ๋ฅผ ์ข
๋ฃํฉ๋๋ค.
(์ด ๋, flush ๋ฉ์๋๊ฐ ์๋ close ๋ฉ์๋๊ฐ ํธ์ถ๋ฉ๋๋ค.)
์ฌ๊ธฐ์ ๋ด์ผํ ์ ์ Transaction AOP๋ฅผ ๋ฒ์ด๋ Controller ๋ ์ด์ด์์๋ถํฐ Entity๋ ์์ ๋ถ๊ฐ๋ฅํ ์ํ๊ฐ ๋๋๋ฐ, ์ด ๋๋ถํฐ๋ ํธ๋์ญ์ ์ด ์ด๋ฏธ ๋๋ ์ํ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ํ์ง๋ง Entity ๊ฐ์ฒด๋ฅผ ์์ /์ญ์ ํ๋ ์์ ์ด ์๋ ์กฐํ๋ฅผ ํ ๋๋ ์๋ฌด๋ฐ ์๊ด์ด ์์ต๋๋ค.
๋ฐ๋ผ์ Entity ๊ฐ์ฒด๋ฅผ ๋ ๋๋งํ๋ ๊ณผ์ ์์ Lazy Loading์ด ๋ฐ์ํด๋ ์กฐํ๋ง ํ๊ธฐ ๋๋ฌธ์ Controller ๋ ์ด์ด์์ ์ํ ๊ฐ๋ฅํฉ๋๋ค.
- JPA๋ฅผ ์ด์ฉํด Entity ๊ฐ์ฒด๋ฅผ ์์ /์ญ์ ํ๋ ๊ฒฝ์ฐ์๋ ๋ฐ๋์ ํธ๋์ญ์ ๋ฒ์ ๋ด์์ ์ํํด์ผ ํ๋ค.
- ํธ๋์ญ์ ๋ฒ์ ๋ฐ์์๋ Entity ์กฐํ ์ธ์๋ ๋ถ๊ฐ๋ฅํ๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๊ฑด ์ด๋จ๊น? ๋ง์ฝ ํธ๋์ญ์ ๋ฒ์ ๋ฐ์ธ Controller, View ๋ด์์ Entity๋ฅผ ์์ ํ๋ค๋ฉด? ์ฐ๋ฆฌ๋ ์ด์ ๊ธ์์ ์์์ฑ ์ปจํ ์คํธ๋ ๋ณ๊ฒฝ ๊ฐ์ง(Dirty Checking) ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก ๋ฐ์ดํฐ ์์ ์ด ๋ฐ๋ก ๋์ด์ผ ํ์ง๋ง ํธ๋์ญ์ ๋ฐ์์๋ ๊ทธ๋ ๊ฒ ๋์ง ์์ต๋๋ค.
- ์์์ฑ ์ปจํ ์คํธ์ ๋ณ๊ฒฝ ๋ด์ฉ์ DB์ ๋ฐ์ํ๋ ค๋ฉด ์์์ฑ ์ปจํ ์คํธ๋ฅผ flush ํด์ผํ๋๋ฐ, Spring์ด ์ ๊ณตํ๋ OSIV๋ ์์ฒญ์ด ๊ธ๋๋ฉด flush๋ฅผ ํธ์ถํ์ง ์๊ณ , close ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฏ๋ก Entity ๊ฐ์ฒด์ ๋ณ๊ฒฝ ๋ด์ฉ์ ๋ฐ์ํ์ง ์๊ณ ์ข ๋ฃํจ.
- ๊ฐ์ ๋ก DI๋ฅผ ์ด์ฉํด Spring ๋ด์์ ์ฌ์ฉํ๋ EntityManager๋ฅผ ์ฌ์ฉํด Controller๋ View์์ flush ๋ฉ์๋๋ฅผ ํธ์ถํด๋ ์ด๋ฅผ ์์ธ ์ฒ๋ฆฌ๋ก ๋ง์๋ฒ๋ฆฌ๋ ์ฝ๋๋ฅผ ์ฝ์ ํด์ ์ด ์ญ์ ์๋จ.
OSIV๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ
์๋ง ๋์น๋ฅผ ์ฑ์ ๋ถ๋ค๋ ๊ณ์๊ฒ ์ง๋ง OSIV๋ฅผ ์ฌ์ฉํ์ง ์๋๋ก ์ค์ ํ ๊ฒฝ์ฐ์๋ ์๋์ ๊ฐ์ด ๋์ํฉ๋๋ค.
์ต์ ์์ ์ค๋ช ํ ๊ทธ๋๋ก View์์ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ข ๋ฃํ๊ธฐ ๋๋ฌธ์ ์ด ๋๋ถํฐ Entity ๊ฐ์ฒด๋ ์ค์์ ์ํ๋ก ์ ํ๋ฉ๋๋ค. ์ด ๋๋ถํฐ๋ ํธ๋์ญ์ ๋ฐ์์ Child Entity๋ฅผ ๋ก๋ฉํ๋ ๋ฑ์ ํ์๊ฐ ์ผ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
OSIV๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ์ ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ
๊ทธ๋ ๋ค๋ฉด OSIV๋ ์ธ์ ์ฐ๋ ๊ฒ์ด ์ข์๊น?
- View์์ Entity ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด ๋ ๋๋ง ํด์ผํ๋ ๊ฒฝ์ฐ. (Spring MVC)
- Entity ๊ฐ์ฒด ๋ด ์ฐ๊ด ๊ฐ์ฒด๋ฅผ View์์ ์ ์ดํด์ผํ๋ ๊ฒฝ์ฐ
- ๊ฐ์ ์์์ฑ ์ปจํ ์คํธ ๋ด์์ ์ฌ๋ฌ ํธ๋์ญ์ ์ ๊ณต์ ํด์ผ ํ๋ ๊ฒฝ์ฐ.
๋ฐ๋๋ก ์ฌ์ฉํ๋ฉด ์คํ๋ ค ๋ ์ด๋๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค.
- Controller์ Service ๋ก์ง์ด 1:1 ๋งคํ์ธ ๊ฒฝ์ฐ
- Service ๋ ์ด์ด์์ ํธ๋์ญ์ ์ด ์ข ๋ฃ๋๋ ๊ฒฝ์ฐ
- Controller์์ Transaction ์ธ์ ๋ณ๋์ ์ฒ๋ฆฌ ์๊ฐ์ด ๊ธด ๋ก์ง์ด ์๋ ๊ฒฝ์ฐ (์: ์ธ๋ถ API ํธ์ถ)
Spring MVC๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ ๋ณดํต Entity ๊ฐ์ฒด๋ฅผ Service Layer ์์ธต๊น์ง ๋์ด์ฌ๋ ค์ ์ฌ์ฉํ๊ฑฐ๋ ์ฌ๋ฌ ํธ๋์ญ์ ์ ๊ณต์ ํด์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ด ๋๊ฐ ์๋๋ผ๋ฉด OSIV์ ํ์ฑํ๋ ์คํ๋ ค DB ์ปค๋ฅ์ ์ ์ค๋ ์ฌ์ฉํ๊ฒ ํ ๋ฟ ๊ถ์ฅํ๋ ์ต์ ์ ์๋๋๋ค.
๊ทธ๋ ์ง๋ง ์ด๋ฐ ๊ฒฝ์ฐ๊ฐ ์์ ์ ์์ต๋๋ค. ์์์ฑ ์ปจํ ์คํธ์์ Lazy Loading(์ง์ฐ ๋ก๋ฉ)์ View์ ๋ ๋๋ง ํ๋ ๊ฒ ๋ฟ ์๋๋ผ REST API ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋ Child Entity๋ฅผ ๋ก๋ฉํ ๋๋ ์ฌ์ฉํฉ๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ View์์ ๋ก๋ฉํ์ง ์๊ณ Service Layer์์ ๊ฐ๊ธ์ ์ด๋ฉด ๋ก๋ฉ์ ๋๋ผ ์ ์๋๋ก ๊ตฌํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
CQRS
API๊ฐ ๋ง์์ง๊ณ ๋น์ฆ๋์ค ๋ก์ง์ด ์ปค์ง๋ฉด OSIV ์ต์ ์์ด ๋น์ฆ๋์ค ๋ ์ด์ด์์ ์ง์ฐ ๋ก๋ฉ์ ์ฃผ๋ ๊ฒ์ด ๋ณต์ก๋๋ฅผ ๋๋ฆฌ๋ ์์ธ์ด ๋ ์ ์์ต๋๋ค. ์ด๋ด ๋๋ Command์ Query๋ฅผ ๋ถ๋ฆฌํ๋ CQRS๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณผ ์ ์์ต๋๋ค.
- OrderService (์์)
- OrderQueryService (์กฐํ)
Spring MVC์ ๊ฐ์ View๊น์ง ๋ด๋นํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ์๋ ํ๋ฉด์ ๋ง์ถฐ Query ์ฑ๋ฅ ์ต์ ํ๊ฐ ํ์ํ๋ฐ, ์ด๋์ ์ฌ์ค MyBatis๋ iBatis๋ฅผ ์ฐ๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๋ถ๋ฆฌํ๊ธฐ ์ํด OSIV๋ฅผ ์ฌ์ฉํ๊ธฐ๋ ํ๋ ๊ฐ์ฅ ํฐ ๊ฒฝ์ฐ์ด์ง๋ง ๋ณดํธ์ ์ผ๋ก ํฐ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋ ์ด์ ๋น์ฆ๋์ค ๋ก์ง์ ํฐ ์ํฅ์ ์ฃผ์ง๋ ์์ต๋๋ค.
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ , ์ ๋ง ํฌ๊ณ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋๋ ์ด ๋์ ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ช ํ๊ฒ ๋ถ๋ฆฌํด์ผ ์ฐจํ ์ ์ง๋ณด์๊ฐ ํธํด์ง๋๋ค. ์กฐํ์ ์์์ ๋ํ ๋น์ฆ๋์ค ๋ก์ง์ ๋ถ๋ฆฌํ๊ณ ์ปค๋ฅ์ ์ ๊ฐ๋ฅํ ๋ง์ด ์ฌํ์ฉํด ์ฌ์ฉํจ์ผ๋ก์จ ๋์ฉ๋ ํธ๋ํฝ ์ฒ๋ฆฌ์ ์กฐ๊ธ์ ์ ์ฐํ๊ฒ ํด์ฃผ๋ ๊ฒ์ด์ฃ .
2022.02.21 - [Programming/Spring] - [Spring boot] Axon Framework๋ก ์์ํ๋ CQRS ๊ธฐ์ด
CQRS๋ฅผ ๊ตฌํํ ์ ์๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ต๋๋ค. ํ์ฌ ์ ๊ฐ ์์ฑํ ๊ธ ์ค์์๋ Axon ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํด Command์ Query๋ฅผ ๋ถ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ์๋๋ฐ, ๊ด์ฌ์๋ค๋ฉด ์ฐธ๊ณ ํด๋ณด์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
๋ง์น๋ฉฐ...
์ฌ๊ธฐ๊น์ง ๊ฐ๋จํ OSIV์ ๋ํด ์์๋ดค์ต๋๋ค. ์ ๋ฆฌํด๋ณด๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
- OSIV๋ Spring์์ ORM์ ์์์ฑ ์ปจํ ์คํธ๋ฅผ View์์๊น์ง ์ฌ์ฉํ ์ ์๋๋ก ์ต์ .
- ํ์ง๋ง ํธ๋์ญ์ ๋ฐ์์๋ Entity์ ์ง์ฐ ๋ก๋ฉ ๋ฑ ์กฐํ๋ง ๊ฐ๋ฅ.
- ์๋ก ๊ฐ๊ธฐ ๋ ๋ฆฝ๋ ํธ๋์ญ์ ์์ ํธ๋์ญ์ ๊ณต์ ๊ฐ๋ฅ
๋ง์ฝ, ์ฌ๋ฌ๋ถ๋ค ์ค ์ ํ๋ฆฌ์ผ์ด์ ์์ Controller์ ์์ ๋ก์ง ํธ์ถ ํ ์ธ๋ถ API๋ฅผ ํธ์ถํ๋ ๋ฑ์ ํ์๋ฅผ ํ๊ณ ์๋ค๋ฉด ์ต์ ํ๋ฅผ ์ํด OSIV ์ต์ ์ ๋ํด ๋ค์ ํ ๋ฒ ์๊ฐํ์ค ํ์๊ฐ ์์ต๋๋ค.
'Programming > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] Spring Advisor์ Pointcut - ์ค์ ํธ (0) | 2022.10.29 |
---|---|
[Spring] Spring Advisor์ Pointcut - ๊ฐ๋ ํธ (0) | 2022.10.10 |
[Spring] Spring Advice๋ก ์ปค์คํ ์ด๋๋ฐ์ด์ค ๋ง๋ค๊ธฐ (0) | 2022.05.16 |
[Spring] Spring AOP - Spring์์๋ AOP๋ฅผ ์ด๋ป๊ฒ ์ด์ฉํ ๊น? (0) | 2022.05.15 |
[Spring] AOP (Aspect-Oriented Programming) ๊ธฐ๋ณธ๊ณผ ๊ฐ๋ (0) | 2022.05.14 |