๐ค 0. DB ํธ๋์ญ์
๋ ์ด์ ์ชผ๊ฐค ์ ์๋ ์ต์ ๋จ์์ ์์ ์ด๋ผ๋ ๊ฐ๋ ์ผ๋ก, commit()์ ํตํด ๋ชจ๋ ์ฑ๊ณตํ๋ ์ง ์๋๋ฉด rollback()์ ํตํด ๋ชจ๋ ์ทจ์๋์ด์ผ ํ๋ ์์ ๋จ์.
ํธ๋์ญ์ ์ DB์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํ๋์ ์์ ๋จ์์ ์ํฉ๋๋ค. ์ฐ๋ฆฌ๊ฐ INSERT, UPDATE, DELETE ๋ฑ์ SQL๋ฌธ์ ์คํํ๋ฉด, ์๋์ผ๋ก ํ ๋ผ์ธ๋ง๋ค ํธ๋์ญ์ ์ด ์ ์ฉ๋์ด Commit์ ์คํํ๊ฒ ๋ฉ๋๋ค.
์ด๋ฌํ ํธ๋์ญ์ ์ ์์ญ์ ์๋์ผ๋ก ์ค์ ํด, ํ ํธ๋์ญ์ ์์ ์ฌ๋ฌ๊ฐ์ ๋ช ๋ น๋ฌธ์ ๋ฃ๋๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
START TRANSACTION;
....
COMMIT;
ํธ๋์ญ์ ์ ์ฐ๋ฆฌ๋ง๋ก '๊ฑฐ๋'๋ผ๊ณ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, A์ B๊ฐ ๊ฑฐ๋๋ฅผ ํ๋ ๊ฒฝ์ฐ A๊ฐ B์๊ฒ ๋์ ์ ๊ธ ํ์ผ๋, B์๊ฒ ์ฌ์ ์ด ์๊ฒจ ๋ฌผ๊ฑด์ ๋ณด๋ด์ง ๋ชปํ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด ๋ด ์๋ค! ์ด ๊ฒฝ์ฐ, A๋ B์๊ฒ ๋์ ๋๋ ค๋ฐ์์ผ๊ฒ ์ฃ ? ์๋ ๊ฑฐ๋๋ฅผ ์์ํ๊ธฐ ์ ์ํฉ์ผ๋ก ๋๋์๊ฐ์ผ ํฉ๋๋ค.
๋ฐ๋ผ์ ๊ฐ๋ฐ์์์ DB ํธ๋์ญ์ ๋ ์ด์ ์ ์ฌํ ์๋ฏธ๋ก ์๊ฐํ๋ฉด ์ข์ต๋๋ค. ๋ค์ํ ์์ ์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๋, ํธ๋์ญ์ ์์ ๋จ์ ๋ด์ ๋ชจ๋ ์์ ์ ์์ํ๋ก ๋๋ฆด ์ ์๋ค๋ ๊ฒ์ด์ฃ .
ํธ๋์ญ์ ์์ ์ฌ์ฉ๋๋ ์ฉ์ด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- Commit : ํธ๋์ญ์ ๋ด๋ถ์ ๋ชจ๋ ์์ ์ ์๋ฃํ๊ณ , ํธ๋์ญ์ ๋ด๋ถ์ ์์ ๋ณ๊ฒฝ์ ๋ชจ๋ ์น์ธํ๊ณ ๋ฐ์ํฉ๋๋ค.
- Rollback : ํธ๋์ญ์ ๋ด๋ถ์ ๋ชจ๋ ์์ ์ ๊ฒฐ๊ณผ์ ๋ฐ์์ํค์ง ์๊ณ , ํธ๋์ญ์ ์์ ์ด์ ์ ์ํ๋ก ๋๋๋ฆฝ๋๋ค.
๐ค 1. @Transactional์ ์ฌ์ฉ๋ฐฉ๋ฒ
์ฐ๋ฆฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ํ๋ ์ ์ํฌ์ธ ์คํ๋ง์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์คํ๋ง์ @Transactional ์ด๋ ธํ ์ด์ ์ ํ์ฉํ ์ ์ธ์ ํธ๋์ญ์ ์ฒ๋ฆฌ๋ฅผ ์ง์ํฉ๋๋ค.
์ด๋ฌํ ์ ์ธ์ ํธ๋์ญ์ ์ด ์ด๋ค ๋ฐฉ์์ผ๋ก ์คํ๋ ์ ์๋์ง์ ๋ํด์๋ ๋ค์ ํฌ์คํ ์์ ์ ๋ฆฌํด๋ณด๋๋ก ํ๊ณ , ์ค๋์ ์ด๋ฌํ ์ด๋ ธํ ์ด์ ๋ฐฉ์์ ํธ๋์ญ์ ์ ์ฉ์ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง์ ๋ํด ์ ๋ฆฌํด ๋ณด๋ ค๊ณ ํฉ๋๋ค.
1. ์ด๋์ ๋ถ์ผ ์ ์๋๊ฐ?
@Transactional์ ๋ฉ์๋, ํด๋์ค ์์ ๋ถ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํด๋น ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋๋, ํ๋์ ํธ๋์ญ์ ์ ๋ฌถ์ฌ ๊ด๋ฆฌ๋๊ฒ ๋ฉ๋๋ค. ์ด๋ฌํ ์ผ์ด ๊ฐ๋ฅ์ผ ๋๋ ์ด์ (์๋์๋ฆฌ)์ ๋ํด์๋ ๋ค์ ํฌ์คํ ์์ ์์๋ณด๋ ค๊ณ ํฉ๋๋ค.
@Transactional์ ๋ฉ์๋์ ํด๋์ค ๋ ๋ฒจ์ ๋ถ์์ ๋, ์ฐ์ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
(์ฐ์ ์์ ๋์) ๋ฉ์๋ > ํด๋์ค > interface method > interface (์ฐ์ ์์ ๋ฎ์)
์ด๋ฌํ ์ฐ์ ์์๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์ ๊ณตํต์ ์ธ ํธ๋์ญ์ ๊ท์น์ ํด๋์ค์, ํน๋ณํ ๊ท์น์ ๋ฉ์๋์ ๋ถ์ด๋ ๊ฒ ์ข์ต๋๋ค.
๋ํ ์๋ฐ ์ด๋ ธํ ์ด์ ์ ์ธํฐํ์ด์ค๋ก๋ถํฐ ์์๋์ง ์๊ธฐ ๋๋ฌธ์ ํด๋์ค ๊ธฐ๋ฐ ํ๋ก์ ๋ AspectJ ๊ธฐ๋ฐ์์ ํธ๋์ญ์ ์ค์ ์ ์ธ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์ธํฐํ์ด์ค ๋ณด๋ค๋ ํด๋์ค์ ์ ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
+ @Transactional์ ์ผ๋ฐ์ ์ผ๋ก Proxy ๋ชจ๋๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ Public ๋ฉ์๋์ ์ค์ ํด์ผ ํฉ๋๋ค. ๋ค๋ฅธ ์ ๊ทผ์ ์ด์์ ๋ํด์๋ ์ฌ์ฉํ์ง ๋ชปํ๊ฑฐ๋, ์๋ฌ๊ฐ ๋ฐ์ํ์ง๋ ์์ง๋ง ๋์ํ์ง ์๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
2. @Transactional์ ์ต์
<์ฌ์ฉ ์์>
@Transactional(isolation = Isolation.READ_COMMITTED,
propagation = Propagation.REQUIRED,
readOnly = true,
timeout = 30,
noRollbackFor = {SQLException.class},
rollbackFor = {EntityNotFoundException.class})
- isolation :
- ํธ๋์ญ์ ์ ๊ฒฉ๋ฆฌ ์์ค ์ค์ , ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ด๋์ ๋ ๊ฐ์ ํ ์ ์๋์ง์ ๋ํ ์์ค ์ค์ ์ด ๊ฐ๋ฅ.
- ๋ท ๋ถ๋ถ์์ ์ถ๊ฐ๋ก ๋ค๋ฃฐ ์์
- propagation :
- ํธ๋์ญ์ ๋์ ๋์ค, ๋ค๋ฅธ ํธ๋์ญ์ ์ ํธ์ถ ํ ๋, ์ด๋ค ๋ฐฉ์์ผ๋ก ๋์ํ๋์ง, ์ ํ๋๋์ง ์ค์ ์ด ๊ฐ๋ฅ.
- ๋ท ๋ถ๋ถ์์ ์ถ๊ฐ๋ก ๋ค๋ฃฐ ์์
- noRollbackFor :
- ํน์ ์์ธ ๋ฐ์ ์ rollback์ด ๋์ํ์ง ์๋๋ก ์ค์
- rollbackFor :
- ํน์ ์์ธ ๋ฐ์ ์ rollback์ด ๋์ํ๋๋ก ์ค์
- timeout :
- ์ง์ ํ ์๊ฐ ๋ด์ ๋ฉ์๋ ์ํ์ด ์๋ฃ๋์ง ์์ผ๋ฉด rollback์ด ๋์ํ๋๋ก ์ค์
- readOnly :
- ํธ๋์ญ์ ์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ค์
3. rollbackFor์ noRollbackFor ์ต์
์ ์ธ์ ํธ๋์ญ์ ์์๋, ๊ธฐ๋ณธ์ ์ผ๋ก RuntimeException์ ๋ํด ๋กค๋ฐฑ์ ํ๋๋ก ์ค์ ์ด ๋์ด์์ต๋๋ค.
By default, a transaction will be rolling back on RuntimeException and Error but not on checked exceptions (business exceptions).
- docs ๋์ค ๋ฐ์ท
๊ทธ๋ฌ๋ Checked Exception์ ๋ํด์๋ ์ด๋ฌํ ๋กค๋ฐฑ ์ฒ๋ฆฌ๊ฐ ๊ธฐ๋ณธ ์ค์ ์ผ๋ก ๋์ด์์ง ์์ต๋๋ค.
๊ทธ๋ ๋ค๊ณ ํด์ "CheckedException์ด๋ผ๊ณ ํด์, ๋ฐ๋์ ๋กค๋ฐฑ์ ํ์ง ๋ง์์ผ ํ๋ค."๋ผ๊ณ ๊ท์ ๋์ด ์๋ ๊ฒ์ ์์ต๋๋ค.
๋ค๋ฅธ ๋ธ๋ก๊ทธ์์ "UncheckedException๊ณผ CheckedException์ ๋ํด ๊ฐ๊ฐ ๋กค๋ฐฑ ์ฒ๋ฆฌ๋ฅผ ํด์ผ ํ๋ค, ํ์ง ๋ง์์ผ ํ๋ค"์ ๊ฐ์ด ๋จ์ธํด์ ์ ๋ฆฌํด ๋์ ๊ธ์ ๋ง์ด ๋ณด์๋๋ฐ, ๋ฐฑ๊ธฐ์ ๋์ ์ ํ๋ธ๋ฅผ ์ฐธ๊ณ ํด ์ด๋ฌํ ์ ์ ์๋ชป๋ ๊ฒ์ด๋ผ๋ ๊ฒ์ ์ง์ ์ ์์์ต๋๋ค.
๋ฐ๋ผ์ ๋กค๋ฐฑ์ ์ฌ๋ถ๋ ์จ์ ํ ๊ฐ๋ฐ์์ ๋ชซ์ ๋๋ค. CheckedException์ด๋ผ๊ณ ํ๋๋ผ๋, ๋กค๋ฐฑ์ด ํ์ํ ์ํฉ์ด๋ฉด rollbackFor ์ต์ ์ ํด๋น Exception class๋ฅผ ์ถ๊ฐํด ๋กค๋ฐฑ์ ์ ๋ํ๋ฉด ๋ฉ๋๋ค.
์ญ์ RuntimeException์์๋, ๋กค๋ฐฑ์ ๊ธ์ง์ํฌ Exception์ด ์๋ค๋ฉด noRollbackFor ์ต์ ์ ์ฌ์ฉํด ๋กค๋ฐฑ์ ํ์ง ์๋๋ก ์ ๋ํ ์ ์์ต๋๋ค.
4. readOnly์ ํจ๊ณผ
readOnly์ ๋ป์ ๋ณด๋ฉด ์ ์ ์๋ฏ์ด, ํด๋น ํธ๋์ญ์ ์ ์ฝ๊ธฐ ์ ์ฉ์ด๋ผ๊ณ ์ ์ธํ๋ ๊ฒ์ ๋๋ค.
readOnly ์ต์ ์ ์ฌ์ฉํ์ ๋์ ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์์ , ์ญ์ , ์ฝ์ ์ฐ์ฐ์ ๋ํด ํ์ฉํ์ง ์๋ ํธ๋์ญ์ ์ด๋ผ๋ ์๋ฏธ๋ก, ์ด๋ฌํ ์ฐ์ฐ์ด ์๋ชป ๋ค์ด๊ฐ ๊ฒฝ์ฐ์ ๋ํด ๋ฐฉ์ด๊ฐ ๊ฐ๋ฅํจ.
- readOnly๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๋ด๋ถ์ ์ธ ์๋ ๊ฐ์ ์ด ๊ฐ๋ฅ.
์ด๋ฌํ ํจ๊ณผ๋ฅผ ๋ณด์์ ๋, ์ฐ๋ฆฌ๋ ํธ๋์ญ์ ์ ์ ์ฉ์ํฌ ๋ ์ฝ๊ธฐ ์ ์ฉ์ด๋ผ๊ณ ๋ช ์ํ ์ ์๋ ๋ถ๋ถ์๋ ๋ฐ๋์ ๋ช ์ํ๋ ๊ฒ์ด ์ข๋ค๋ ์ฌ์ค์ ์ ์ ์์ต๋๋ค.
์ค๋์ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ํ ์ ๋ฆฌ์ด๋ฏ๋ก ์ด๋ฌํ readOnly์ ๋ด๋ถ ๋์์ ๋ํด์๋ ๋ค์ ํฌ์คํ ์์ ์ ๋ฆฌํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ค 2. ํธ๋์ญ์ ์ ๊ณ ๋ฆฝ ๋จ๊ณ
๋ชจ๋ DB ํธ๋์ญ์ ์ ๊ฒฉ๋ฆฌ ์์ค(๊ณ ๋ฆฝ ๋จ๊ณ)์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ํํ ์ฐ๋ฆฌ๊ฐ ์๊ณ ์๋ ํธ๋์ญ์ ์ ์์ฑ ACID ์ค, I๊ฐ ๋ฐ๋ก isolation์ธ ๊ณ ๋ฆฝ์ฑ์ ์๋ฏธํฉ๋๋ค. ์ด๋ฌํ ๊ฒฉ๋ฆฌ ์์ค์ ๋ํ ์ค์ ์ผ๋ก ๊ณ ๋ฆฝ์ฑ์ ํ๋ณดํ ์ ์๋ ๊ฒ์ด์ฃ .
์๋ฒ ํ๊ฒฝ์ ๊ฐ๋ฐํ๋ฉด, ๋ฉํฐ์ฐ๋ ๋ ํ๊ฒฝ์์ ๊ฐ๋ฐ๋๊ธฐ ๋๋ฌธ์ ๋์์ ์ฌ๋ฌ ๊ฐ์ ํธ๋์ญ์ ์ด ์คํ๋ ์ ์์ต๋๋ค. ์ด ๋ ๊ณ ๋ฆฝ์ฑ์ ๋๊ฒ ์ค์ ํ๋ค๋ฉด, ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ํด ์ํฅ์ ๋ ๋ฐ์ ์ ์์ผ๋ฏ๋ก ๊ณ ๋ฆฝ์ฑ์ ํญ์ ๊ณ ๋ ค๋์ด์ผ ํ ์ฌํญ์ ๋๋ค.
ํ์ง๋ง, ๊ณ ๋ฆฝ์ฑ์ ๋๊ฒ ์ค์ ํ๋ฉด ๋์์ฑ์ด ๋จ์ด์ง๊ฒ ๋ฉ๋๋ค. ์ฆ ๊ณ ๋ฆฝ์ฑ์ ๋๊ฒ ์ค์ ํ๋ฉด ๋์์ฑ์ด ๋จ์ด์ง๊ณ , ๋์์ฑ์ ๋์ด๋ฉด ๊ณ ๋ฆฝ์ฑ์ด ๋จ์ด์ง๊ฒ ๋ฉ๋๋ค. ์ฆ ๋ ๊ฐ์ง์ ์์ฑ์ trade-off ๊ด๊ณ์ ์๋ ๊ฒ์ด์ฃ .
๊ทธ๋ผ ๊ณ ๋ฆฝ์ฑ์ ๋ฎ์ท์ ๋ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ๋ ๋ฌด์์ด ์์๊น์?
์ด๋ฌํ ๋ฌธ์ ๋ DB ํธ๋์ญ์ ์ ๊ฒฉ๋ฆฌ์์ค ์ค์ ๊ณผ ํจ๊ป ์์๋ณด๋๋ก ํฉ์๋ค!
@Transactional(isolation = Isolation.DEFAULT)
๊ธฐ๋ณธ์ผ๋ก ์ ํ๋ ํธ๋์ญ์ ์ ๊ณ ๋ฆฝ๋จ๊ณ์ ๋๋ค. ์์ ์ด ์ฌ์ฉํ๊ณ ์๋ datasource์ ์ํด ์ด๋ฌํ DEFAULT ๊ฐ์ด ์ ํด์ง๋๋ค.
์ฆ, ์์ผ๋ก ๋์ฌ
- READ_UNCOMMITTED
- READ_COMMITTED
- REPEATABLE_READ
- SERIALIZABLE
์ค์์ DataSource๊ฐ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ์ ํํ ๊ฒฉ๋ฆฌ ์์ค์ ์ ํํ๊ฒ ๋ฉ๋๋ค.
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
๊ฐ์ฅ ๋ฎ์ ๋จ๊ณ์ ๊ณ ๋ฆฝ ์์ค์ ๋๋ค.
์ด๋ฆ์์ ์ ์ ์๋ฏ์ด, ํธ๋์ญ์ ์ฒ๋ฆฌ ์ค ํน์ ์ปค๋ฐ๋๊ธฐ ์ด์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฅธ ํธ๋์ญ์ ์ด ์ฝ๋ ๊ฒ์ ํ์ฉํฉ๋๋ค.
์ด๋ค ์ฌ์ฉ์๊ฐ A๋ผ๋ ๋ฐ์ดํฐ๋ฅผ B๋ผ๋ ๋ฐ์ดํฐ๋ก ๋ณ๊ฒฝํ๋ ๋์ ๋ค๋ฅธ ์ฌ์ฉ์๋ B๋ผ๋ ์์ง ์๋ฃ๋์ง ์์(Uncommitted ํน์ Dirty) ๋ฐ์ดํฐ B๋ฅผ ์ฝ์ ์ ์์ต๋๋ค.
READ_UNCOMMITTED์์ ๋ฐ์ํ๋ Dirty Read๋ ๋ค์๊ณผ ๊ฐ์ ์ํฉ์์ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค.
A ํธ๋์ญ์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๊ณ , B ํธ๋์ญ์ ์์ ์์ง ์ปค๋ฐ๋์ง ์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๋ค์์ต๋๋ค.
๊ทธ๋ฌ๋ A ํธ๋์ญ์ ์ด ๋กค๋ฐฑ์ด ๋๋ค๋ฉด, A์ ์ ๋ ฅ๋ ๋ฐ์ดํฐ๋ ์ ์ฉ๋์ง ์๊ณ ๋์๊ฐ๋๋ค. ํ์ง๋ง B ํธ๋์ญ์ ์์๋ ์ด๋ฏธ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๋ค์์ผ๋ฏ๋ก, ์กด์ฌํ์ง ์๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ํ๊ฒ ๋๋ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ํ์์ ๋ฌด๊ฒฐ์ฑ์ ๊นจ๋จ๋ฆฌ๋ฏ๋ก, Dirty Read๊ฐ ์ํํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
@Transactional(isolation = Isolation.READ_COMMITTED)
์ด๋ฌํ Dirty Read ํ์์ ๋ง๊ธฐ ์ํด ๊ฒฉ๋ฆฌ์์ค์ ํ ๋จ๊ณ ๋์ผ ์ ์์ต๋๋ค. ์ด ๊ฒฉ๋ฆฌ ์์ค์ ๋ฐ๋ก READ_COMMITTED์ ๋๋ค.
์ปค๋ฐ๋ ๋ฐ์ดํฐ์ ๋ํด์๋ง ๋ค๋ฅธ ํธ๋์ญ์ ์ด ํด๋น ๋ฐ์ดํฐ์ ์ ๊ทผํด์ ์ฝ์ด๋ค์ผ ์ ์๋๋ก ํ๋ ๊ฒ์ด์ฃ .
์ปค๋ฐ์ด ์ ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๋ค์ผ ์ ์์ผ๋ฏ๋ก Dirty Read์ ๊ฐ์ ํ์์ ์ผ์ด๋์ง ์์ ๊ฒ์ ๋๋ค.
ํ์ง๋ง, READ_COMMITTED์๋ ํ ์ด ์๋ ๊ฒ์ ์๋๋๋ค.
์์ ๊ฐ์ Flow๋ฅผ ๋ณด๊ฒ ๋๋ฉด, ํธ๋์ญ์ A์์๋ x=1์ ์กฐ๊ฑด์ ๊ฐ์ง ๋ฐ์ดํฐ๋ฅผ 2ํ ์๋ํ๊ณ ์์ต๋๋ค.
ํ์ง๋ง ๊ทธ ์ฌ์ด์ ํธ๋์ญ์ B๊ฐ ์คํ๋์ด x=1์ ์กฐ๊ฑด์ ๊ฐ์ง ๋ฐ์ดํฐ์ ๋ํด ์์ / ์ญ์ ๋ฅผ ์๋ํ๊ณ ์ปค๋ฐ์ ํ ์ํ์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด, A ํธ๋์ญ์ ์์ ์ฒซ ๋ฒ์งธ Read์, ๋ ๋ฒ์งธ Read๋ ์๋ก ๋ค๋ฅธ ๊ฐ์ ๊ฐ๊ฑฐ๋ (์์ ์ ๊ฒฝ์ฐ), ๋ ๋ฒ์งธ Read์์ ์์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ผ๋ ค๊ณ ํ ์ ์์ต๋๋ค.(์ญ์ ์ ๊ฒฝ์ฐ)
์ด๋ฌํ ํ์์ Non-repeatable reads๋ผ๊ณ ํฉ๋๋ค. ํ ํธ๋์ญ์ ๋ด์์ ๊ฐ์ ์กฐ๊ฑด์ ๋ํ read๊ฐ ๋์ผํ์ง ์์ ๊ฐ์ ์ป๋๋ค๋ ํ์์ด์ฃ .
@Transactional(isolation = Isolation.REPEATABLE_READ)
์กฐ๊ธ ๋ ๊ฒฉ๋ฆฌ ์์ค์ ๋์ฌ๋ณด๊ฒ ์ต๋๋ค. REPEATABLE_READ๋ก ๊ฒฉ๋ฆฌ ์์ค์ ์ฌ๋ฆฌ๊ฒ ๋๋ฉด, ํ ํธ๋์ญ์ ์์ ๊ฐ์ ๋ฐ์ดํฐ์ ๋ํด ๋ฐ๋ณต ์กฐํ๋ฅผ ํ๋๋ผ๋ ๊ฐ์ ๊ฐ์ ์ป๊ฒ ๋ฉ๋๋ค.
์ด๋ ๊ฒ ๊ฒฉ๋ฆฌ ์์ค์ ๋์์์๋, ์์ ๊ฐ์ ์ํฉ์์ ์ฝ๊ฐ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค.
๋ฐฉ๊ธ๊ณผ๋ ๋ค๋ฅด๊ฒ ๋ฒ์๋ฅผ ์ง์ ํ read๋ฅผ ์คํํ๊ณ , ํธ๋์ญ์ B์์๋ ํด๋น ๋ฒ์ ๋ด๋ถ์ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๊ณ ์์ต๋๋ค.
๋ถ๋ช ํธ๋์ญ์ A์์ ๊ฐ์ ์กฐ๊ฑด์ผ๋ก ๋ฐ์ดํฐ ์กฐํ๋ฅผ ํ์ง๋ง, ์ฒซ ๋ฒ์งธ์ ๋ ๋ฒ์งธ์ Read๋ ๊ฐ๊ฐ ๊ฒฐ๊ณผ ๊ฐ์ด ๋ค๋ฅด๊ฒ ๋์ต๋๋ค.
์ด๋ฌํ ํ์์ Phantom Read (์ ๋ น์ฝ๊ธฐ)๋ผ๊ณ ํฉ๋๋ค.
@Transactional(isolation = Isolation.SERIALIZABLE)
๊ฐ์ฅ ๋จ์ํ๋ฉด์ ๊ฐ์ฅ ์๊ฒฉํ ๊ฒฉ๋ฆฌ ์์ค์ ๋๋ค. ํ ํธ๋์ญ์ ์์ ์ฝ๊ณ ์ฐ๋ ๋ด์ฉ์ ๋ํด ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ ๋๋ก ์ ๊ทผํ ์ ์์ต๋๋ค.
์์์ ๋์จ ๋ชจ๋ ํ์์ ๋ํด ์ ๊ฑฐ๊ฐ ๊ฐ๋ฅํ์ง๋ง, ๋์์ฑ์ด ์ง๋์น๊ฒ ๋จ์ด์ ธ ์ฌ์ฉ์ ์ง์ํฉ๋๋ค.
๊ฐ๋จํ๊ฒ ๊ฐ ๊ฒฉ๋ฆฌ ์์ค์ด ์ด๋ค ๊ฒ์์ ํ์ธํ์ง๋ง, MySQL์์ ๊ฒฉ๋ฆฌ ์์ค์ ์ค์ ์ ๋ฐ๋ผ ์ด๋ค ๋ฐฉ์์ผ๋ก ๋์ํ๋์ง๋ ์์ง ๋ชปํฉ๋๋ค.
์ด๋ฐ ๋ถ๋ถ์ ๋ํด์ ์ถ๊ฐ์ ์ผ๋ก ์ ๋ฆฌํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ค 3. ํธ๋์ญ์ ์ ์ ํ ๋จ๊ณ
ํธ๋์ญ์ ์ ํ๋, ํธ๋์ญ์ ์ ๊ฒฝ๊ณ์์ ์ด๋ฏธ ์งํ ์ค์ธ ํธ๋์ญ์ ์ด ์์ ๋, ๋๋ ์์ ๋ ์ด๋ป๊ฒ ๋์ํ ๊ฒ์ธ์ง๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ์์ ์๋ฏธํฉ๋๋ค.
์๋ฅผ ๋ค์ด, A ๋ฉ์๋์ ํธ๋์ญ์ ์ ์ค์ ํ๊ณ , B ๋ฉ์๋์ ํธ๋์ญ์ ์ ์ค์ ํ์ต๋๋ค. A ๋ฉ์๋ ๋ด๋ถ์์ B ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค.
์ด ๊ฒฝ์ฐ, A ๋ฉ์๋์ ํธ๋์ญ์ ์ด ๋ชจ๋ ๋๋์ง ์์ ์ํ์์, B ๋ฉ์๋์ ํธ๋์ญ์ ์ด ์คํ๋ฉ๋๋ค. ๊ทธ๋ผ ์ด๋ฌํ B์ ์ฝ๋๋ ์ด๋ค ํธ๋์ญ์ ์์์ ์คํ๋์ด์ผ ํ ๊น์?
์ด๋ฌํ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ณผ ์ ์์ต๋๋ค.
- A์์ ์ด๋ฏธ ์์ํ ํธ๋์ญ์ ์ ํธ์
- ์์์ ์ด๋ฏธ ์์๋ A ํธ๋์ญ์ ๊ณผ ๋ฌด๊ดํ๊ฒ ๋ ๋ฆฝ์ ์ธ B ํธ๋์ญ์ ์ ์คํ
์ด๋ฐ ๋์ ๋ฐฉ์์ ๊ฒฐ์ ํ๋ ๊ฒ์ด ๋ฐ๋ก ์ ํ ๋จ๊ณ์ ์กฐ์ ์ ๋๋ค.
์ด๋ฌํ ์ ํ๋จ๊ณ์ ์กฐ์ ์ @Transactional์ propagation ์ต์ ์ ์ ํํด์ ์กฐ์ ํ ์ ์์ต๋๋ค.
@Transactional(propagtion = Propagation.REQUIRED)
๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ํธ๋์ญ์ ์ ํ ์์ฑ์ ๋๋ค. ์งํ์ค์ธ ํธ๋์ญ์ ์ด ์๋ค๋ฉด ์๋ก ์์ํ๊ณ , ์ด๋ฏธ ์คํ๋ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ํด๋น ํธ๋์ญ์ ์ผ๋ก ํธ์ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ด๋ฌํ ์ ํ ์์ฑ์ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ๋ค์ํ ๋ฐฉ์์ผ๋ก ์๋ก ๊ฒฐํฉํด ํ๋์ ํธ๋์ญ์ ์ผ๋ก ๊ตฌ์ฑํ๊ธฐ ์ํํฉ๋๋ค.
์๋์ ๊ฐ์ด ๊ธฐ๋ณธ์ ์ธ ํธ๋์ญ์ ์ ํ ์์ฑ์ ์ฑํํ๊ณ ์์ด์, ๊ตณ์ด propagation ๊ฐ์ ์ค์ ํ์ง ์๋๋ผ๋ ์๋ ์ ์ฉ ๋ฉ๋๋ค.
@Transactional(propagtion = Propagation.REQUIRES_NEW)
ํญ์ ์๋ก์ด, ๋
๋ฆฝ์ ์ธ ํธ๋์ญ์
์ ์คํํ๊ฒ ํ๋ ์ ํ ์ ๋ต์
๋๋ค. ์์์ ์์๋ ํธ๋์ญ์
์ด ์๋ ์๋ ์๊ด์์ด ์๋ก์ด ํธ๋์ญ์
์ ๋ง๋ค์ด์ ๋
์์ ์ผ๋ก ๋์๋๊ฒ ํฉ๋๋ค. ๋
๋ฆฝ์ ์ธ ํธ๋์ญ์
์ด ๋ณด์ฅ๋์ด์ผ ํ๋ ์ฝ๋์ ์ ์ฉ์ํฌ ์ ์์ต๋๋ค.
๋ํ ๊ฐ๊ฐ์ ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋๋๋ผ๋, ์ ํ ์ํฅ์ ๋ผ์น์ง ์์ต๋๋ค.
@Transactional(propagtion = Propagation.MANDATORY)
์์์ ๋ณด์๋, REQUIRED ์ ํ ์ ๋ต๊ณผ ๋์ผํ๊ฒ ๋ถ๋ชจ ํธ๋์ญ์ ์ผ๋ก ํธ์ ์ด ๋๋ค๋ ์ ์์ ๊ต์ฅํ ๋น์ทํ์ง๋ง, ๋ถ๋ชจ ํธ๋์ญ์ ์ด ์๋ค๋ฉด ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค๋ ์ฐจ์ด์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
Mandatory๋ 'ํ์์ ์ธ'์ด๋ผ๋ ๋ป์ผ๋ก ๋ถ๋ชจ ํธ๋์ญ์ ์ด ๋ฐ๋์ ์กด์ฌํด์ผ ํ๋ ์๋ฏธ๋ก ํด๋น ๋จ๊ณ ์๋ช ์ ํ ๊ฒ ๊ฐ์ต๋๋ค.
@Transactional(propagtion = Propagation.SUPPORTED)
์์์ ๋ณด์๋, REQUIRED ์ ํ ์ ๋ต๊ณผ ๋์ผํ๊ฒ ๋ถ๋ชจ ํธ๋์ญ์ ์ผ๋ก ํธ์ ์ด ๋๋ค๋ ์ ์์ ๊ต์ฅํ ๋น์ทํ์ง๋ง, ๋ถ๋ชจ ํธ๋์ญ์ ์ด ์๋ค๋ฉด xํธ๋์ญ์ ์ ์์ฑํ์ง ์๋ ์ฐจ์ด์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
@Transactional(propagtion = Propagation.NESTED)
- ๋ถ๋ชจ ํธ๋์ญ์ ์ด ์๋ ๊ฒฝ์ฐ : ์๋ก์ด ํธ๋์ญ์ ์ ์์ฑํด์ ์๋ํฉ๋๋ค.
- ๋ถ๋ชจ ํธ๋์ญ์ ์ด ์๋ ๊ฒฝ์ฐ : ์์ ์์๋ค๊ณผ๋ ๋ค๋ฅด๊ฒ, '์ค์ฒฉ ํธ๋์ญ์ '์ ์์ฑํฉ๋๋ค.
์ค์ฒฉ ํธ๋์ญ์ ์ ๋ด๋ถ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํด ๋กค๋ฐฑ์ด ๋๋ค๋ฉด, ์ค์ฒฉ ํธ๋์ญ์ ๋ง ๋กค๋ฐฑํฉ๋๋ค.
์ค์ฒฉ ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋์ด๋, ๋ถ๋ชจ ํธ๋์ญ์ ์๋ ์ํฅ์ ๋ผ์น์ง ์์ต๋๋ค.
์ค์ฒฉ ํธ๋์ญ์ ์ ๋ถ๋ชจ ํธ๋์ญ์ ์ด ๋ชจ๋ ๋๋๊ณ ์ปค๋ฐ๋๋ ์์ ์ ๊ฐ์ด ์ปค๋ฐ๋ฉ๋๋ค. (๋ชจ๋ ์ปค๋ฐ์ ๋ถ๋ชจ ํธ๋์ญ์ ์ด ๋๋ ๋ ํ ๋ฒ.)
๋ถ๋ชจ ํธ๋์ญ์ ์ด ๋กค๋ฐฑํ๋ฉด, ์ค์ฒฉ ํธ๋์ญ์ ๋ ๋กค๋ฐฑ๋ฉ๋๋ค.
@Transactional(propagtion = Propagation.NEVER)
ํธ๋์ญ์ ์ ์์ฑํ์ง ์๊ณ , ๋ถ๋ชจ ํธ๋์ญ์ ์ด ์กด์ฌํ๋ค๋ฉด ์์ธ๋ฅผ ๋ฐ์์ํต๋๋ค.
๐ ์ถ์ฒ
[๋์] ํ ๋น์ ์คํ๋ง 3.1
[๋งํฌ] https://www.youtube.com/watch?v=_WkMhytqoCc&t=152s (๋ฐฑ๊ธฐ์ ๋ ์ ํ๋ธ)
[๋งํฌ] https://tecoble.techcourse.co.kr/post/2021-05-25-transactional/ (tecoble)
[๋งํฌ] https://data-make.tistory.com/738
[๋งํฌ] https://brush-up.github.io/java/java-springboot-transactional/
[๋งํฌ] https://www.codeproject.com/Articles/1190420/Database-Transactions-with-Spring-Framework
[๋งํฌ] https://incheol-jung.gitbook.io/docs/q-and-a/db/isolation-level
[๋งํฌ] https://steady-coding.tistory.com/562