@Transactional
๋ค์ด๊ฐ๋ฉด์
์คํ๋ง์์ ํธ๋์ญ์ ์
@Transactional
์ ์ ์ธํ๋ฉด ์ ์ฉํด๋น ๊ธฐ๋ฅ์ AOP๋ฅผ ํตํด ๊ตฌํ.
AOP๊ฐ ์ ์ฉ๋์๋ ์ง ํ์ธํ๊ธฐ ์ํด์๋
.getClass()
๋ฅผ ํตํดํด๋์ค ์ด๋ฆ์ ํ์ธํด๋ ๋จ. ($$SpringCGLIB...
)ํน์
AopUtils
๋ผ๋ ํด๋์ค์์ ์ ๊ณตํ๋ ๋ฉ์๋๋ฅผ ํตํด ํ์ธํด๋ณผ ์ ๋ ์์.๊ทธ๋ฆฌ๊ณ
public
๋ฉ์๋์๋ง ์ ์ฉ์ด ๊ฐ๋ฅ. (private
,protected
,package-visible
์ ์ ์ฉ์ด ์๋จ.)protected
,package-visible
์ ๊ฒฝ์ฐ ์ธ๋ถ์์ ํธ์ถ์ ๊ฐ๋ฅํ๋, ์คํ๋ง ์์ฒด์์ ์ ์ฉ๋์ง ์๋๋ก ๋ง๊ณ ์์.
์คํ๋ง์์ ํธ๋์ญ์ ์ ๋ํ ๊ด๋ฆฌ๋
TransactionSynchronizationManager
์์ ๊ด๋ฆฌ.ThreadLocal
์ด๋ผ, ๊ฐ ์ค๋ ๋ ๋ณ๋ก ๊ด๋ฆฌ๋๋ค๊ณ ๋ณด์ฌ์ง.
@Transactional ์ต์
์์์ ์ฐ์ ์์?
์คํ๋ง์์ ์ฐ์ ์์?
ํญ์ ๋ ๊ตฌ์ฒด์ ์ผ๋ก ์์ธํ ๊ฒ์ด ๋ ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง.
ํด๋์ค vs ๋ฉ์๋ -> ๋ฉ์๋
์ธํฐํ์ด์ค vs ํด๋์ค(์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ) -> ํด๋์ค (๋ ์์ธํ ๊ฒ์ด๋ฏ๋ก)
์ด์ ๊ฐ์ด ์ ์ธ๋์ด์์ ๋, ํ๋ก์๊ฐ ์ ์ฉ๋ LevelSerivce#write๋ฅผ ํธ์ถ ํ๋ฉด, readOnly ์ต์ ์ด false๋ก ์ ์ฉ๋์ด์ ์คํ๋จ.
์? ๋ ๊ตฌ์ฒด์ ์ธ ๊ฒ(๋ฉ์๋) ์ ์ ์ฉ๋ ์ต์ ์ด ๋จผ์ ์ ์ฉ๋๊ธฐ ๋๋ฌธ์
@Transactional with Interface
์ธํฐํ์ด์ค์ ํธ๋์ญ์ ์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ์คํ๋ง์์ ๊ถ์ฅํ์ง ์๋ ๋ฐฉ๋ฒ.
์?
AOP๋ฅผ ์ ์ฉํ๋ ๋ฐฉ์์ ๋ฐ๋ผ, ์ธํฐํ์ด์ค์ ์ฌ์ฉํ์ ๊ฒฝ์ฐ AOP๊ฐ ์๋ํ ๋๋ก ๋์ํ์ง ์์ ์ ์์.
์ฆ ์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ง, ์ ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ
์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์ vs ํด๋์ค ๊ธฐ๋ฐ ํ๋ก์
JDK Dynamic proxy vs CGLIB
์๋ง๋ Spring ๊ธฐ๋ณธ AOP ์ ์ฉ ๊ธฐ์ ์ด CGLIB ์ฆ ํด๋์ค ๊ธฐ๋ฐ์ด๋ฏ๋ก, ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ด์ ์ด๋ ๊ฒ ๊ถ์ฅํ๋ ๋ฏ
@Transactional ์ฌ์ฉํ๋ฉด์, ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์
๋ด๋ถ ํธ์ถ
Controller์์ CallService#external (ํ๋ก์ ์ ์ฉ๋ ๊ฐ์ฒด๋ฅผ ๊ฑฐ์ณ์) ๋ฅผ ํธ์ถ ํ๋ค๊ณ ๊ฐ์ .
๊ทธ๋ฌ๋ฉด external ์์, internal() ์ด ํธ์ถ ๋ ๊ฒ.
์ด๋ด ๋
@Transactional
์ด ์ ์ฉ ๋ ๊น? (txActive = true?)์๋๋ค.
์?
Proxy ๊ฐ์ฒด๋ฅผ ๊ฑฐ์ณ์ ํธ์ถ๋๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์,
@Transactional
์ด ๋ถ์ด์์ด๋ ์๋ฌด๋ฐ ๊ธฐ๋ฅ์ ํ์ง ๋ชปํจ.์ฆ AOP๊ฐ ์ ์ฉ๋์ง ์์.
์ ๋ฆฌํ์๋ฉด Spring์์ AOP๊ฐ ๋์ํ๋ ๋ฐฉ์ ๋๋ฌธ์ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์.
ํด๊ฒฐ์
internal()
๋ก ํธ์ถ๋๋ ๋ถ๋ถ์ ๋ค๋ฅธ ํด๋์ค๋ก ๋ถ๋ฆฌํ์ฌ AOP๊ฐ ์ ์ฉ๋ ์ํ๋ก ํธ์ถ๋๋๋ก ์์ ํ๋ฉด ๋จ.
@PostContruct ์ @Transactional์ ๊ฐ์ด ์ฌ์ฉํ ๊ฒฝ์ฐ, ํธ๋์ญ์
์ด ์ ์ฉ๋์ง ์๋ ๋ฌธ์
์คํ๋ง ๋น ๋ผ์ดํ ์ฌ์ดํด
์คํ๋ง ์ปจํ ์ด๋ ์์ฑ
์คํ๋ง ๋น ์์ฑ
์์กด๊ด๊ณ์ฃผ์
์ด๊ธฐํ ์ฝ๋ฐฑ์ฌ์ฉ @PostConstruct
๋น ์ฌ์ฉ
์๋ฉธ์ ์ฝ๋ฐฑ @PreDestro
๋ผ์ดํ ์ฌ์ดํด๋ก ๋ฏธ๋ฃจ์ด๋ณด์, 4๋ฒ์์
@PostContruct
์คํํจ.4๋ฒ์์
@Transactional
์ ๋ํ ํ๋ก์ ๋น์ด ์คํ๋ง ์ปจํ ์ด๋์ ๋ชจ๋ ์ ์ฉ๋์๋ค๊ณ ๋ณด์ฅํ ์ ์์๋ฏ@Transactional
์ ๋จผ์ ์์๊ฐ ์๋จ์ ์์ด๋.. ์๋ ๋ฏ.
BeanPostProcessor๋ 3~5๋ฒ ์ฌ์ด์ ๋์ํ๋ฏ๋ก.
ํด๊ฒฐ?
@EventListener(value = ApplicationReadyEvent.class)
์ด์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ชจ๋ ์ฌ๋ผ์์ ๋, ํธ์ถ๋๋๋ก.
@Transaciotnal ์ต์
ํธ๋์ญ์
์์ธ, ๋กค๋ฐฑ
unchecked exception (Runtime exception, Error) ๋ฐ์ ์, ๋กค๋ฐฑํจ.
checked exeception (Exception) ๋ฐ์ ์, ํธ๋์ญ์ ์ปค๋ฐ.
๋ก๊ทธ ์ต์ ์ ํตํด, ํด๋น ํธ๋์ญ์ ์งํ์ ๋ํ ๋ก๊ทธ๋ฅผ ๋ชจ๋ ํ์ธํ ์ ์์.
์ ์ธ์ฒดํฌ ์์ธ๋ ๋กค๋ฐฑ, ์ฒดํฌ ์์ธ๋ ์ปค๋ฐ?
์ฒดํฌ ์์ธ๋ ๋น์ฆ๋์ค ์์ธ๊ฐ ์์.
๋น์ฆ๋์ค ์์ธ? ์์คํ ์ ์์ธ๋ ์๋์ง๋ง, ์์ธ๊ฐ ๋ฐ์ (์๊ณ ๋ถ์กฑ ๊ฐ์)
๊ทธ๋์ ๋กค๋ฐฑ๊น์ง ํ์ง ์์๋ ๋ ๋.
์๋ฅผ ๋ค์ด, ๋ง์ฝ ๋กค๋ฐฑํด๋ฒ๋ฆฌ๋ฉด ๊ณ ๊ฐ์ด ์ฃผ๋ฌธํ ์ฃผ๋ฌธ ์ ๋ณด๊น์ง ์์ด์ง๋ ์ผ์ด ๋ฐ์. (๋ถํ์ํ..)
์ธ์ฒดํฌ ์์ธ๋ ๋ณต๊ตฌ ๋ถ๊ฐ๋ฅํ๋ฏ๋ก, ๋์ ์ ์ฌ์ฉ์๊ฐ ์๊ฒํด์ผํจ. ์์คํ ์์ธ ์๋ฅผ ๋ค๋ฉด ๋คํธ์ํฌ ์ด์..
์ค์ฒฉ๋ ํธ๋์ญ์
์์์ ์ปค๋ฐ๊ณผ ๋กค๋ฐฑ
ํธ๋์ญ์ ์ ํ๋ ๊ธฐ๋ณธ ๊ฐ์ (required)
ํธ๋์ญ์ ์งํ ์ค์, ๊ทธ ํธ๋์ญ์ ์ด ์์ง ๋๋์ง ์์๋(์ปค๋ฐ, ๋กค๋ฐฑ) ๋ฐ ๊ทธ ๋ด๋ถ์์ ๋๋ค๋ฅธ ํธ๋์ญ์ ์ด ์์ฑ๋๋ค๋ฉด, ์ธ, ๋ด๋ถ ํธ๋์ญ์ ๋ชจ๋ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ์ฌ๊ฒจ์ง (์คํ๋ง ๊ธฐ๋ณธ ๋ฐฉ์)
ํธ๋์ญ์ ์งํ ์์, ๋ ๋ค๋ฅธ ํธ๋์ญ์ ์ ์์ฑํ๋ค๋ฉด..
ํ๋์ ๋ฌผ๋ฆฌ์ ์ธ ํธ๋์ญ์ ์ด ์กด์ฌํ๋ฉฐ, ๊ทธ ์์๋ ๋ ผ๋ฆฌ์ ํธ๋์ญ์ ์ด 2๊ฐ ์๋ค๊ณ ๋ณผ ์ ์์.
์ฆ ๋ฌผ๋ฆฌ ํธ๋์ญ์ = ๋ ผ๋ฆฌ ํธ๋์ญ์ + ๋ ผ๋ฆฌ ํธ๋์ญ์
์ด ํ๋์ ํธ๋์ญ์ ์ผ๋ก ๋ฌถ์ด๋ ๊ฑด ๋ฌผ๋ฆฌ์ ์ผ๋ก ์ฆ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋์์ ์ด์ผ๊ธฐ ํ๋ ๊ฒ.
๋กค๋ฐฑ ์ ๋ต?
๋ ผ๋ฆฌ ํธ๋์ญ์ ์ค ํ๋๋ผ๋ ๋กค๋ฐฑ๋๋ค๋ฉด, ๋ฌผ๋ฆฌ์ ํธ๋์ญ์ ์ ๋กค๋ฐฑ๋จ.
์ฆ ๋ ผ๋ฆฌ ํธ๋์ญ์ ๋ค ๋ชจ๋๊ฐ ๋ฌธ์ ์์ด ์ปค๋ฐ ๋์ด์ผ, ๋ฌผ๋ฆฌ์ ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๋ค๋ ์ด์ผ๊ธฐ ์ด๊ณ , ๋ฌผ๋ฆฌ์ ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๋ค๋ ๊ฑด ๊ทธ๋์์ผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ปค๋ฐ์ด ๋๋ค๋ ์ด์ผ๊ธฐ
ํธ๋์ญ์ ์คํ ์์, ํ์ฌ ์ํ๋ฅผ ํ์ธ (TransactionSynchronizationManager๋ฅผ ํตํด) ํ์ฌ ์งํ๋๊ณ ์๋ ํธ๋์ญ์ ์ด ์๋ ์ง ํ์ธ ํ๋ค์์, ์์ผ๋ฉด ํด๋น ํธ๋์ญ์ ์ ์ด์ฉํ๋๋ก ํจ.
ํด๋น ํธ๋์ญ์ ์ ์ฐธ์ฌํ๋ค? == ์๋ฌด๊ฒ๋ ์ํ๋ค๋ ๋ป.
๋ฌผ๋ฆฌ์ปค๋ฅ์ ์ ํ๋ํ๊ฑฐ๋.. ์ด๋ฐ ์ผ๋ จ์ ์์ ์ ํ์ง ์ํ๋ค๋ ๋ป.
ํ๋์ ๋ฌผ๋ฆฌ์ ํธ๋์ญ์ ์ด ์๊ณ , 2๊ฐ์ ๋ ผ๋ฆฌ์ ํธ๋์ญ์ ์ด ์๋ค๊ณ ๊ฐ์ ํ์.
์ธ๋ถ ํธ๋์ญ์ (๋จผ์ ์์ํ ํธ๋์ญ์ ) ์ ์ ์์ ์ผ๋ก ์ปค๋ฐ๋์๋๋ฐ, ๋ด๋ถ ํธ๋์ญ์ (๋์ค์ ์์ํ)์ด ๋กค๋ฐฑ๋๋ค๋ฉด?
๊ฒฐ๊ณผ์ ์ผ๋ก ๋ฌผ๋ฆฌ์ ํธ๋์ญ์ ์ ๋กค๋ฐฑ๋ ๊ฒ์ด๊ณ .
๋ด๋ถ ํธ๋์ญ์ ์์ ๋กค๋ฐฑ๋์์ ๋, ํธ๋์ญ์ ์ ์์ฑ๊ฐ(rollback-only) ๋ณ๊ฒฝํ์ฌ, ์ธ๋ถ ํธ๋์ญ์ ์ด ์ปค๋ฐ ์ ์ ํด๋น ์์ฑ๊ฐ์ ์ฒดํฌํ๋๋ฐ (์ปค๋ฐํด๋ ๋ ์ง), ์ด ๊ฐ์ด
true
์ด๊ธฐ ๋๋ฌธ์, ๋กค๋ฐฑ๋๋ค.ํธ๋์ญ์ ๋งค๋์ ๋ ์ ๊ท ํธ๋์ญ์ ์ธ์ง ์๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ, ์ง์ง ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋กค๋ฐฑ ํ ์ง, ์๋๋ฉด ์ ์ญ ํธ๋์ญ์ ์ ๋งํฌ๋ง ํ ์ง ๊ฒฐ์ ํจ.
์ ๋ฆฌํ์๋ฉด, ๋ด๋ถ ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋๋ฉด, ๋ฌผ๋ฆฌ์ ํธ๋์ญ์ ์ ๋กค๋ฐฑํ์ง ์์. ๊ทธ ๋์ ์
rollback-only = true
์ ๋งํฌํจ.๊ทธ๋์ ์ธ๋ถ ํธ๋์ญ์ ์ด ์ปค๋ฐํ๊ธฐ ์ ์, ํด๋น ๊ฐ์ ๋ณด๊ณ , ๋กค๋ฐฑํด์ผ ๋ง์ง ํ๋จ. ๋งํฌ ๋์ด์๋ค๋ฉด ๋ฌผ๋ฆฌ์ ํธ๋์ญ์ ์ ๋กค๋ฐฑํ๊ฒ ๋จ.
๊ทธ๋ฆฌ๊ณ
UnexpectedRollbackException
์์ธ๋ฅผ ๋์ง.
ํธ๋์ญ์
์ ํ
REQUIRED
๊ธฐ๋ณธ
๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํจ.
๊ธฐ์กด ํธ๋์ญ์ ์์ผ๋ฉด, ์ฐธ์ฌํจ.
๊ธฐ์กด ํธ๋์ญ์ ์์ผ๋ฉด ์์ฑํจ.
REQUIRED_NEW
ํญ์ ์๋ก์ด ํธ๋์ญ์ ์ ์์ฑํ๋ ์ต์
๊ธฐ์กด ํธ๋์ญ์ ์์ผ๋ฉด, ์๋ก ์์ฑ.
๊ธฐ์กด ํธ๋์ญ์ ์์ผ๋ฉด, ์๋ก ์์ฑ.
์ฆ ์ธ๋ถ, ๋ด๋ถ๋ฅผ ์์ ํ ๋ถ๋ฆฌํด์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ. ์ฆ ๋ฌผ๋ฆฌ์ ์ผ๋ก ์์ ํ ๋ถ๋ฆฌํ๋ ๋ฐฉ๋ฒ์.
ํด๋น ์ต์ ์ ํธ๋์ญ์ ์ด ํธ์ถ๋๋ ์์ ์, ์ปค๋ฅ์ ํ์ ์ปค๋ฅ์ ์ด ๋ถ์กฑํ๋ฉด.. ๋ฐ๋๋ฝ์ด ๊ฑธ๋ฆด ๊ฐ๋ฅ์ฑ ์์.
timeout์ด ์๊ธฐ ๋๋ฌธ์, ์ด๋ ์์ ์์๋ ๋กค๋ฐฑ๋๊ฒ ์ง๋ง..
์? ์ด๊ฒ ์ ๋กค๋ฐฑ๋๋๊ฑฐ์ง? ์ถ๊ฐ์ ์ผ๋ก ์ฝ์ด๋ด์ผํ ๊ฒ.
SUPPORT
NOT_SUPPORT
MANDATORY
NEVER
NESTED
๊ธฐ์กด ํธ๋์ญ์ ์ด ์์ผ๋ฉด, ์๋ก์ด ํธ๋์ญ์ ์์ฑ.
๊ธฐ์กด ํธ๋์ญ์ ์ด ์์ผ๋ฉด, ์ค์ฒฉ ํธ๋์ญ์ ์ ์์ฑ
์ค์ฒฉ ํธ๋์ญ์ ?
์ด ํธ๋์ญ์ ์ ์ธ๋ถ ํธ๋์ญ์ ์ ์ํฅ์ ๋ฐ์ง๋ง, ์ด ํธ๋์ญ์ ์ด ์ธ๋ถ ํธ๋์ญ์ ์ ์ํฅ์ ์ฃผ์ง ์์.
e.g ์ธ๋ถ ํธ๋์ญ์ ๋กค๋ฐฑ -> ์ค์ฒฉ ํธ๋์ญ์ ๋กค๋ฐฑ, ์ค์ฒฉ ํธ๋์ญ์ ๋กค๋ฐฑ -> ์ธ๋ถ ํธ๋์ญ์ ์ปค๋ฐ ๊ฐ๋ฅ
ํธ๋์ญ์
์ ํ, ์ต์
์ ์ ์ฉ
isolation
,timeout
,readOnly
๋ฑ์ ์ต์ ์ ํธ๋์ญ์ ์ด ์๋ก ์์ํ ๋๋ง ์ ์ฉ๋จ.e.g
REQUIRED
์์ ๊ธฐ์กด ํธ๋์ญ์ ์ด ์๊ณ , ์๋ก์ด ํธ๋์ญ์ ์ ์์ํ ๋ ์ ์ฉ, ์ฐธ์ฌํ ๋๋ ํด๋น ํธ๋์ญ์ ์ ์ต์ ์ด ์์ด๋ ์ ์ฉ์ด ์๋๋ค. (์ธ๋ถ ํธ๋์ญ์ ์ต์ ์ด ์ ์ฉ๋จ.)
์ฐธ๊ณ
Last updated