Search
β˜•

OSIV 에 κ΄€ν•˜μ—¬

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 일 λ•ŒλŠ” νŠΈλžœμž­μ…”λ„ μ–΄λ…Έν…Œμ΄μ…˜ λ°”κΉ₯μ—μ„œλ„ em이 μ—΄λ €μžˆλ‹€. ν•˜μ§€λ§Œ μ€€μ˜μ†μƒνƒœμ΄λ‹€. κ·Έλž˜μ„œ μ‘°νšŒλŠ” κ°€λŠ₯ν•˜λ‹€. ν•˜μ§€λ§Œ νŠΈλžœμž­μ…”λ„ μ–΄λ…Έν…Œμ΄μ…˜ λ°”κΉ₯μ΄κΈ°λ•Œλ¬Έμ— 더티체킹을 ν•˜μ§€ μ•ŠλŠ”λ‹€. κ·Έλž˜μ„œ 변경점에 λŒ€ν•œ μ—…λ°μ΄νŠΈλ₯Ό ν•˜μ§€ μ•ŠλŠ”λ‹€.
β€’
κ·Έ μ΄μœ λŠ” νŠΈλžœμž­μ…”λ„ μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ μ„Έμ…˜μ„ μ—° 것이 μ•„λ‹ˆκ³  λƒ…λ‹€ interceptor μ—μ„œ μ„Έμ…˜μ„ μƒμ„±ν–ˆκΈ° λ•Œλ¬Έμ΄λ‹€.
β€’
false 일 λ•ŒλŠ” 컀λ„₯μ…˜, μ„Έμ…˜ λͺ¨λ‘ λ‹«ν˜€μžˆλ‹€. κ·Έλž˜μ„œ λ ˆμ΄μ§€ λ‘œλ”© μ‘°νšŒλ„ λ˜μ§€ μ•ŠλŠ”λ‹€.
β€’
EM 생성 β†’ 컀λ„₯μ…˜ νšλ“ β†’ νŠΈλžœμž­μ…˜ 생성 순
β—¦
setAutoCommit ν•˜λ©΄ 컀λ„₯μ…˜μ„ λ’€μ—μ„œ νšλ“ν•˜λŠ”λ° 이 λ•ŒλŠ”?
β–ͺ
ConnectionHandle 을 μƒμ„±ν•΄μ„œ 컀λ„₯μ…˜μ„ μ‹€μ œλ‘œ μ–»λŠ” κ²ƒκ³ΌλŠ” λ‹€λ₯΄λ‹€.
β–ͺ
ConnectionHandle 생성은 μ„Έμ…˜λ§ŒμœΌλ‘œ κ°€λŠ₯ν•˜λ‹€.
β–ͺ
κ·Έλž˜μ„œ νŠΈλžœμž­μ…˜ begin 호좜 μ‹œ TransactionStatus 만 ACTIVE 둜 λ°”κΎΌλ‹€! μ‹€μ œ 컀λ„₯μ…˜μ„ νšλ“ν•˜μ§€ μ•Šκ³ !