EntityManager ์์ฑ ์์
โข
ํธ๋์ญ์
์์ ์
โข
JpaTransactionManager
โฆ
doBegin()
โช
createEntityManagerForTransaction() ์ผ๋ก ์๋ก์ด EM ์์ฑ ์์ฒญ
โฆ
createEntityManagerForTransaction()
โช
obtainEntityManagerFactory() ๋ก EMF ํ๋(ํ๋๋ก ๊ฐ์ง๊ณ ์์)
โช
EntityManagerFactoryInfo ์ createNativeEntityManager() ํธ์ถ
โข
AbstractEntityManagerFactoryBean(EntityManagerFactoryInfo ์ถ์ ๊ตฌํ์ฒด)
โฆ
createNativeEntityManager()
โช
SessionFactoryImpl ์ createEntityManager() ํธ์ถ
โข
SessionFactoryImpl
โฆ
createEntityManager()
โช
openSession() ํธ์ถ
โฆ
openSession()
โช
new SessionImpl(sessionFactory, this);
โข
SessionImpl
โฆ
์์ฑ์
โช
์์์ฑ ์ปจํ
์คํธ, ์ก์
ํ ๋ฑ ์์ฑ
EntityManager ๋ผ์ดํ์ฌ์ดํด
โข
open-in-view ๊ฐ true ๋ผ๋ฉด
โฆ
DispatcherServlet ์ doDispatch ๋ฉ์๋์์
โฆ
ha.handle() ํ ๋ค(์ค์ ์ปจํธ๋กค๋ฌ ๋ถ๋ฅด๋ ๋ฉ์๋)
โฆ
processDispatchResult() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ close ๋ฅผ ํ๋ค.
โข
false ๋ผ๋ฉด
โฆ
APTM ์ commit() ๋ฉ์๋ ์์ processCommit() ํธ์ถ
โฆ
processCommit() ์์ cleanupAfterCompletion() ํธ์ถ
โฆ
cleanupAfterCompletion() ์์ JTM ์ doCleanupAfterCompletion() ํธ์ถ
โฆ
JTM ์ doCleanupAfterCompletion() ์์ EntityManagerFactoryUtils ์ closeEntityManager() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ close
โข
๊ทธ๋ ๋ค๋ฉด ์ด ๋์ ์ฐจ์ด๋ ์ด๋์ ๋ฐ์ํ๋๊ฐ?
โฆ
์ผ๋จ true ๋ฉด HandlerInterceptor ๋ก WebRequestHandlerInterceptorAdapter ๊ฐ ์ถ๊ฐ๋ก ๋ฑ๋ก๋๋ค.
โฆ
์ฌ๊ธฐ์ close ๋ฅผ ํ๋ค.
โข
๊ทธ๋ ๋ค๋ฉด true ์ผ ๋๋ ์ APTM ์ commit ๋ฉ์๋์์ processCommit() ์ ํธ์ถํ์ง ์๋๊ฐ?
โฆ
APTM ์ cleanupAfterCompletion ๋ฉ์๋์์ JTM ์ doCleanupAfterCompletion() ์ ํธ์ถํ๊ธฐ ์ํด์๋ if ๋ถ๊ธฐ๋ฌธ์ status.isNewTransaction() ์ด true ๊ฐ ๋์ด์ผ ํ๋๋ฐ ์ฌ๊ธฐ์ ํต๊ณผํ์ง ๋ชปํ๋ค.
โฆ
์ฆ Service ๊ณ์ธต์ Transactional ์ด๋
ธํ
์ด์
์ผ๋ก ํธ๋์ญ์
์ ์ด๊ธฐ ์ ์ด๋ฏธ ํธ๋์ญ์
์ด ์ด๋ ค ์๋ ์ํ์ธ ๊ฒ.
โข
๊ทธ๋ฌ๋ค. ์ด๋ฏธ ํธ๋์ญ์
์ ์ด์ด๋ฒ๋ฆฐ ๊ฒ์ด๋ค. ๊ทธ๋ผ ํธ๋์ญ์
์ ์ฐ ๊ฐ์ฅ ์ ๋ ฅํ ์ฉ์์๋ WebRequestHandlerInterceptorAdapter ์ธ ๊ฒ ๊ฐ์๋ค. interceptor ๋ผ์ preHandle ์ด ์๋ค. ์ฌ๊ธธ ๋๋ฒ๊ทธ ์ฐ์ด๋ณด์๋ค.
โฆ
DispatcherServlet ์์ ํธ๋ค๋ฌ์ ํธ๋ค๋ฌ์ด๋ํฐ๋ฅผ ์ฐพ๊ณ ํธ๋ค๋ฌ์ด๋ํฐ์ handle ์ ํธ์ถํ๊ธฐ ์ preHandle ๋ก ์ธํฐ์
ํฐ๋ฅผ ํธ์ถํ๋ค.
โฆ
WebRequestHandlerInterceptorAdapter ์ preHandle ์์ ํ๋๋ก ๋ฑ๋ก๋ requestInterceptor ์ preHandle ์ ์์ฒญํ๋ค.
โฆ
๋ฑ๋ก๋ requestInterceptor ๋ OpenEntityManagerInViewInterceptor ์ด๊ณ ์ด ๊ฐ์ฒด์ preHandle ๋ฉ์๋์์ EMF ๋ฅผ ์ป์ ๋ค createEntityManager ๋ก EM ์ ์์ฑํ๋ค.
โฆ
์ด๋ ์ปค๋ฅ์
์ ๋น๋ ค๊ฐ์ง ์์! ๋จ์ํ ์ธ์
์ ์ด๊ณผ em ์ ์์ฑํ ๋ฟ
OSIV ์ ๊ธฐ๋ฅ
โข
true ์ผ ๋
โฆ
Lazy ์ผ ๋
โช
ํ๋ก์๋ก ์๋ ๊ฐ์ฒด ์กฐํ ๊ฐ๋ฅ(์ฟผ๋ฆฌ ๋ฐ์)
โช
ํ๋ก์๋ก ์๋ ๊ฐ์ฒด ๋ณ๊ฒฝ ๋ถ๊ฐ(๋ํฐ ์ฒดํน ๋ถ๊ฐ๋ฅ) ํ์ง๋ง ์๋ฌ X
โข
false ์ผ ๋
โฆ
Lazy ์ผ ๋
โช
ํ๋ก์๋ก ์๋ ๊ฐ์ฒด ์กฐํ ์ LazyInitializationException: could not initialize proxy [com.example.tosstemp.Team#1] - no Session] with root cause ์๋ฌ ๋ฐ์
โช
๋ณ๊ฒฝ๋ ๋น์ฐํ ๋ถ๊ฐ
๊ฒฐ๋ก
โข
true ์ผ ๋๋ ํธ๋์ญ์
๋ ์ด๋
ธํ
์ด์
๋ฐ๊นฅ์์๋ ์ปค๋ฅ์
์ด ์ด๋ ค์๋ค. ํ์ง๋ง ์ค์์์ํ์ด๋ค. ๊ทธ๋์ ์ปค๋ฅ์
์ด ์ด๋ ค์์ด์ ์กฐํ๋ ๊ฐ๋ฅํ๋ค. ํ์ง๋ง ํธ๋์ญ์
๋ ์ด๋
ธํ
์ด์
๋ฐ๊นฅ์ด๊ธฐ๋๋ฌธ์ ๋ํฐ์ฒดํน์ ํ์ง ์๋๋ค. ๊ทธ๋์ ๋ณ๊ฒฝ์ ์ ๋ํ ์
๋ฐ์ดํธ๋ฅผ ํ์ง ์๋๋ค.
โข
๊ทธ ์ด์ ๋ ํธ๋์ญ์
๋ ์ด๋
ธํ
์ด์
์ผ๋ก ์ธ์
์ ์ฐ ๊ฒ์ด ์๋๊ณ ๋
๋ค interceptor ์์ ์ธ์
์ ์์ฑํ๊ธฐ ๋๋ฌธ์ด๋ค.
โข
false ์ผ ๋๋ ์ปค๋ฅ์
, ์ธ์
๋ชจ๋ ๋ซํ์๋ค. ๊ทธ๋์ ๋ ์ด์ง ๋ก๋ฉ ์กฐํ๋ ๋์ง ์๋๋ค.
โข
EM ์์ฑ โ ์ปค๋ฅ์
ํ๋ โ ํธ๋์ญ์
์์ฑ ์
โฆ
setAutoCommit ํ๋ฉด ์ปค๋ฅ์
์ ๋ค์์ ํ๋ํ๋๋ฐ ์ด ๋๋?
โช
ConnectionHandle ์ ์์ฑํด์ ์ปค๋ฅ์
์ ์ค์ ๋ก ์ป๋ ๊ฒ๊ณผ๋ ๋ค๋ฅด๋ค.
โช
ConnectionHandle ์์ฑ์ ์ธ์
๋ง์ผ๋ก ๊ฐ๋ฅํ๋ค.
โช
๊ทธ๋์ ํธ๋์ญ์
begin ํธ์ถ ์ TransactionStatus ๋ง ACTIVE ๋ก ๋ฐ๊พผ๋ค! ์ค์ ์ปค๋ฅ์
์ ํ๋ํ์ง ์๊ณ !