@Transactional
์ด ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ฉด ๋ฉ์๋๊ฐ ํธ๋์ญ์ ๊ฒฝ๊ณ์ ํฌํจ๋์ด์ผ ํจ์ ๋ํ๋ ๋๋ค. Spring์ ์ด ์ด๋ ธํ ์ด์ ์ ๊ฐ์งํ๊ณ ํด๋น ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋ ํธ๋์ญ์ ์ ์์ํ๋ฉฐ, ๋ฉ์๋๊ฐ ์ข ๋ฃ๋ ๋ ํธ๋์ญ์ ์ ์ปค๋ฐํ๊ฑฐ๋ ๋กค๋ฐฑํฉ๋๋ค.
์ฃผ์ ํน์ง ๋ฐ ์ฃผ์ ์ฌํญ
1. Propaging(์ ํ ์ต์
):
ํธ๋์ญ์ ์ ์ ํ ๋์์ ์ง์ ํ๋ค
์ข
๋ฅ
REQUIRED
(ํ์ํ ๊ฒฝ์ฐ):ํธ๋์ญ์ ์ด ์ด๋ฏธ ์กด์ฌํ๋ฉด ๊ทธ๊ฒ์ ์ฌ์ฉํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ก์ด ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
@Transactional(propagation = Propagation.REQUIRED) public void requiredMethod() { // ์ด๋ฏธ ํธ๋์ญ์ ์ด ์กด์ฌํ๋ฉด ์ฌ์ฉํ๊ณ , ์์ผ๋ฉด ์๋ก์ด ํธ๋์ญ์ ์์ }
SUPPORTS
(์ง์ํ๋ ๊ฒฝ์ฐ):ํธ๋์ญ์ ์ด ์ด๋ฏธ ์กด์ฌํ๋ฉด ๊ทธ๊ฒ์ ์ฌ์ฉํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ํธ๋์ญ์ ์์ด ์คํ๋ฉ๋๋ค.
@Transactional(propagation = Propagation.SUPPORTS) public void supportsMethod() { // ์ด๋ฏธ ํธ๋์ญ์ ์ด ์กด์ฌํ๋ฉด ์ฌ์ฉํ๊ณ , ์์ผ๋ฉด ํธ๋์ญ์ ์์ด ์คํ }
MANDATORY
(ํ์):ํธ๋์ญ์ ์ด ์ด๋ฏธ ์กด์ฌํด์ผ๋ง ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
@Transactional(propagation = Propagation.MANDATORY) public void mandatoryMethod() { // ํธ๋์ญ์ ์ด ๋ฐ๋์ ์กด์ฌํด์ผ ํจ. ์์ผ๋ฉด ์์ธ ๋ฐ์ }
REQUIRES_NEW
(ํญ์ ์๋ก์ด ํธ๋์ญ์ ):ํญ์ ์๋ก์ด ํธ๋์ญ์ ์ ์์ํฉ๋๋ค. ์ด๋ฏธ ์กด์ฌํ๋ ํธ๋์ญ์ ์ ์ผ์ ์ค๋จ๋ฉ๋๋ค.
@Transactional(propagation = Propagation.REQUIRES_NEW) public void requiresNewMethod() { // ํญ์ ์๋ก์ด ํธ๋์ญ์ ์์. ๊ธฐ์กด ํธ๋์ญ์ ์ ์ผ์ ์ค๋จ }
NOT_SUPPORTED
(ํธ๋์ญ์ ์ง์ ์ ํจ):ํธ๋์ญ์ ์ ์ง์ํ์ง ์์์ ํธ๋์ญ์ ์ธ๋ถ์์ ์คํ๋ฉ๋๋ค. ์ด๋ฏธ ์กด์ฌํ๋ ํธ๋์ญ์ ์ ์ผ์ ์ค๋จ๋ฉ๋๋ค.
@Transactional(propagation = Propagation.NOT_SUPPORTED) public void notSupportedMethod() { // ํธ๋์ญ์ ์์ด ์คํ. ๊ธฐ์กด ํธ๋์ญ์ ์ ์ผ์ ์ค๋จ }
NEVER
(ํธ๋์ญ์ ์ฌ์ฉ ๊ธ์ง):ํธ๋์ญ์ ์ ์ฌ์ฉํด์๋ ์ ๋๋ฉฐ, ํธ๋์ญ์ ์ด ์ด๋ฏธ ์กด์ฌํ๋ฉด ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
@Transactional(propagation = Propagation.NEVER) public void neverMethod() { // ํธ๋์ญ์ ์ ์ฌ์ฉํด์๋ ์ ๋จ. ์ด๋ฏธ ์กด์ฌํ๋ฉด ์์ธ ๋ฐ์ }
NESTED
(์ค์ฒฉ๋ ํธ๋์ญ์ ):ํ์ฌ ํธ๋์ญ์ ์ด ์กด์ฌํ๋ฉด ์ค์ฒฉ ํธ๋์ญ์ ์ ์์ํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ์ผ๋ฐ ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
@Transactional(propagation = Propagation.NESTED) public void nestedMethod() { // ํ์ฌ ํธ๋์ญ์ ์ด ์กด์ฌํ๋ฉด ์ค์ฒฉ ํธ๋์ญ์ ์์, ๊ทธ๋ ์ง ์์ผ๋ฉด ์ผ๋ฐ ํธ๋์ญ์ ์์ }
2. Isolation(๊ฒฉ๋ฆฌ ์์ค):
ํธ๋์ญ์ ์ ๊ฒฉ๋ฆฌ ์์ค์ ์ง์ ํ๋ค
์ข
๋ฅ
READ_UNCOMMITTED
(๋ฏธํ์ธ ์ฝ๊ธฐ):๋ฌธ์ ์ : Dirty Read (๋๋ฌ์ด ์ฝ๊ธฐ)
๋ค๋ฅธ ํธ๋์ญ์ ์์ ์์ง ์ปค๋ฐ๋์ง ์์ ๋ณ๊ฒฝ ๋ด์ฉ์ ์ฝ์ ์ ์์ต๋๋ค.
@Transactional(isolation = Isolation.READ_UNCOMMITTED) public void readUncommittedMethod() { // ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ปค๋ฐ๋์ง ์์ ๋ณ๊ฒฝ ๋ด์ฉ์ ์ฝ์ ์ ์์ }
์์:
A ์ฌ์ฉ์๊ฐ 10000์์ ์ํ ๊ณ์ข์ ์ ๊ธํ๋ ํธ๋์ญ์ ์ ์์ํ์ง๋ง ์์ง ์ปค๋ฐํ์ง ์์์ต๋๋ค. ์ด ๋, B ์ฌ์ฉ์๊ฐ ๊ณ์ข ์์ก์ ์กฐํํ๋ฉด 10000์์ด ๋ํด์ง ์์ก์ ๋ณผ ์ ์์ต๋๋ค. ๋ง์ฝ A ์ฌ์ฉ์๊ฐ ํธ๋์ญ์ ์ ๋กค๋ฐฑํ๋ฉด B ์ฌ์ฉ์๋ ์๋ชป๋ ์ ๋ณด๋ฅผ ๋ณธ ๊ฒ์ด ๋ฉ๋๋ค.
READ_COMMITTED
(ํ์ธ ์ฝ๊ธฐ):๋ฌธ์ ์ : Non-Repeatable Read (๋น๋ฐ๋ณต ์ฝ๊ธฐ)
๋ค๋ฅธ ํธ๋์ญ์ ์์ ์ปค๋ฐ๋ ๋ณ๊ฒฝ ๋ด์ฉ๋ง ์ฝ์ ์ ์์ต๋๋ค.
@Transactional(isolation = Isolation.READ_COMMITTED) public void readCommittedMethod() { // ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ปค๋ฐ๋ ๋ณ๊ฒฝ ๋ด์ฉ๋ง ์ฝ์ ์ ์์ }
์์:
A ์ฌ์ฉ์๊ฐ ์์ ์ ๊ณ์ข ์์ก์ ์กฐํํ์ ๋ 50000์์ด ๋์ต๋๋ค. ๊ทธ ์ฌ์ด B ์ฌ์ฉ์๊ฐ A ์ฌ์ฉ์์ ๊ณ์ข์์ 20000์์ ์ถ๊ธํ์ต๋๋ค. A ์ฌ์ฉ์๊ฐ ๋ค์ ์์ก์ ์กฐํํ๋ฉด 30000์์ด ๋์ต๋๋ค. ๊ฐ์ ํธ๋์ญ์ ๋ด์์ ๋ ๋ฒ์ ์กฐํ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฆ ๋๋ค.
REPEATABLE_READ
(๋ฐ๋ณต ๊ฐ๋ฅํ ์ฝ๊ธฐ):๋ฌธ์ ์ : Phantom Read (์ ๋ น ์ฝ๊ธฐ)
ํธ๋์ญ์ ์ด ์์ํ ๋ ์ฝ์ ๋ฐ์ดํฐ๋ ํด๋น ํธ๋์ญ์ ๋์ ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ํด ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
@Transactional(isolation = Isolation.REPEATABLE_READ) public void repeatableReadMethod() { // ํธ๋์ญ์ ๋์ ์ฝ์ ๋ฐ์ดํฐ๋ ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ํด ๋ณ๊ฒฝ๋์ง ์์ }
์์:
A ์ฌ์ฉ์๊ฐ 30์ธ ์ดํ์ ๊ณ ๊ฐ์ ์กฐํํ์ ๋ 5๋ช ์ด ๋์ต๋๋ค. ๊ทธ ์ฌ์ด B ์ฌ์ฉ์๊ฐ ์๋ก์ด 30์ธ ์ดํ์ ๊ณ ๊ฐ์ ์ถ๊ฐํ์ต๋๋ค. A ์ฌ์ฉ์๊ฐ ๋ค์ 30์ธ ์ดํ์ ๊ณ ๊ฐ์ ์กฐํํ๋ฉด 6๋ช ์ด ๋์ต๋๋ค.
SERIALIZABLE
(์ง๋ ฌํ ๊ฐ๋ฅ):ํธ๋์ญ์ ๋ค์ด ์์ฐจ์ ์ผ๋ก ์คํ๋์ด ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ํฉ๋๋ค.
@Transactional(isolation = Isolation.SERIALIZABLE) public void serializableMethod() { // ์ฝ๋ }
์์:
A ์ฌ์ฉ์๊ฐ ์์ ์ ๊ณ์ข ์์ก์ ๋ณ๊ฒฝํ๋ ํธ๋์ญ์ ์ ์์ํ๋ฉด, ๊ทธ ๋์ B ์ฌ์ฉ์๋ A ์ฌ์ฉ์์ ๊ณ์ข์ ์ด๋ ํ ์์ ๋ ์ํํ ์ ์์ต๋๋ค. A ์ฌ์ฉ์์ ํธ๋์ญ์ ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค
๋์์ฑ ๋ฌธ์
Dirty Reads (์ค์ผ๋ ์ฝ๊ธฐ):
ํ ํธ๋์ญ์ ์์ ๋ณ๊ฒฝ๋ (๊ทธ๋ฌ๋ ์์ง ์ปค๋ฐ๋์ง ์์) ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฅธ ํธ๋์ญ์ ์์ ์ฝ๋ ๊ฒฝ์ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ก ์ธํด ์์ง ํ์ ๋์ง ์์ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ ์ ์ํํ ์ ์์ต๋๋ค.
ํด๊ฒฐ๋ฐฉ๋ฒ:
READ_COMMITTED
์ด์์ ๊ฒฉ๋ฆฌ ์์ค์ ์ฌ์ฉํ์ฌ Dirty Reads๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ปค๋ฐ๋ ๋ฐ์ดํฐ๋ง ์ฝ๊ฒ ๋ฉ๋๋ค.
Non-Repeatable Reads (๋น๋ฐ๋ณต ๊ฐ๋ฅํ ์ฝ๊ธฐ):
ํ ํธ๋์ญ์ ๋์ค์ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ ๋ฒ ์ด์ ์ฝ์ ๋, ๋ ๋ฒ์งธ ์ฝ๊ธฐ์์ ์ฒซ ๋ฒ์งธ ์ฝ๊ธฐ์ ๋ค๋ฅธ ๊ฐ์ ์ป๋ ๊ฒฝ์ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ํด ํด๋น ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์๊ธฐ ๋๋ฌธ์ ๋๋ค.
ํด๊ฒฐ๋ฐฉ๋ฒ:
REPEATABLE_READ
์ด์์ ๊ฒฉ๋ฆฌ ์์ค์ ์ฌ์ฉํ์ฌ Non-Repeatable Reads๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ํธ๋์ญ์ ์ด ์์๋ ๋ ์ฝ์ ๋ฐ์ดํฐ๋ ํด๋น ํธ๋์ญ์ ๋์ ๋ณ๊ฒฝ๋์ง ์๋๋ก ๋ณด์ฅ๋ฉ๋๋ค.
Phantom Reads (ํ์ ์ฝ๊ธฐ):
ํ ํธ๋์ญ์ ๋์ค์ ํน์ ์กฐ๊ฑด์ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ ๋ฒ ์ด์ ์ฝ์ ๋, ๋ ๋ฒ์งธ ์ฝ๊ธฐ์์ ์ฒซ ๋ฒ์งธ ์ฝ๊ธฐ์์ ๋ณด์๋ ๋ฐ์ดํฐ์ ์์ ๋ค๋ฅด๊ฒ ๋ํ๋๋ ๊ฒฝ์ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ํด ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ๋๊ฑฐ๋ ์ญ์ ๋์๊ธฐ ๋๋ฌธ์ ๋๋ค.
ํด๊ฒฐ๋ฐฉ๋ฒ:
SERIALIZABLE
๊ฒฉ๋ฆฌ ์์ค์ ์ฌ์ฉํ์ฌ Phantom Reads๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ํธ๋์ญ์ ๋ค์ด ์์ฐจ์ ์ผ๋ก ์คํ๋์ด, ํ ํธ๋์ญ์ ์ด ์คํ๋๋ ๋์ ๋ค๋ฅธ ํธ๋์ญ์ ์์ ๋ฐ์ดํฐ์ ์ถ๊ฐ๋ ์ญ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ํฉ๋๋ค.
Timeout (์๊ฐ ์ด๊ณผ):
timeout
์ต์ ์ ํด๋น ํธ๋์ญ์ ์ด ์ง์ ๋ ์๊ฐ ๋ด์ ์๋ฃ๋์ง ์์ผ๋ฉด ๊ฐ์ ๋ก ๋กค๋ฐฑ๋ฉ๋๋ค.@Transactional(timeout = 5) // 5์ด public void timeoutMethod() { // ์ด ํธ๋์ญ์ ์ 5์ด ๋ด์ ์๋ฃ๋์ง ์์ผ๋ฉด ๋กค๋ฐฑ๋ฉ๋๋ค. }
Read-only (์ฝ๊ธฐ ์ ์ฉ):
readOnly
์ต์ ์ ํด๋น ํธ๋์ญ์ ๋ด์์ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์์ ์ด ๋ฐ์ํ๋ฉด ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ฝ๊ธฐ ์ ์ฉ ์์ ์์๋ ์ฑ๋ฅ ํฅ์์ด ์์ ์ ์์ต๋๋ค.@Transactional(readOnly = true) public Account getAccount(Long id) { // ์ด ๋ฉ์๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ๋ง ํด์ผ ํฉ๋๋ค. ๋ฐ์ดํฐ ์์ ์ ํ๋ฉด ์ ๋ฉ๋๋ค. return accountRepository.findById(id).orElse(null); }
์ฑ๋ฅ ํฅ์ ์ด์ :
์ต์ ํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ง ๋์:
๋๋ถ๋ถ์ RDBMS๋ ์ฌ๋ฌ ์ ํ์ ๋ฝํน ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ๊ด๋ จ๋ ๋ฝ(์: ์ฐ๊ธฐ ๋ฝ)์ ํ๋ํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์ด๋ก ์ธํด ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์ ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ํด ๋ธ๋กํน๋๋ ๋น๋๊ฐ ์ค์ด๋ค ์ ์์ต๋๋ค.
์: ์์ ์ ์ฌ๊ณ ํ์ธ ์์คํ ์์, ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ์ฌ๊ณ ๋ฅผ ํ์ธํ๋ ๊ฒฝ์ฐ์, ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฌ๊ณ ์ ๋ณด๋ฅผ ๋น ๋ฅด๊ฒ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด ์๊ธฐ ๋๋ฌธ์, ์ฐ๊ธฐ ๋ฝ ์์ด ์ ๋ณด๋ฅผ ์กฐํํ ์ ์์ด, ๋ธ๋กํน ์์ด ๋์์ ์ฌ๋ฌ ์ฌ์ฉ์์ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๋ฒ์ ๊ด๋ฆฌ์ ๋ฝํน ์ต์ํ:
ORM ๋๊ตฌ(์: Hibernate)๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ์ถ์ ํ๊ธฐ ์ํด ๋ด๋ถ์ ์ผ๋ก ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ ๋ํ ๋ฒ์ ๋ฒํธ๋ฅผ ์ฌ์ฉํ์ฌ, ๋ ์ฌ์ฉ์๊ฐ ๋์์ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ ์ํฉ(๋์์ฑ ๋ฌธ์ )์ ํด๊ฒฐํ๋๋ฐ ๋์์ ์ค๋๋ค. ๊ทธ๋ฌ๋ ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์์๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด ์์ผ๋ฏ๋ก, ์ด๋ฌํ ๋ฒ์ ๊ด๋ฆฌ๊ฐ ํ์ ์์ด์ง๋๋ค.
์: ์ํ์ ๊ณ์ข ์์ก ํ์ธ ์์คํ ์์, ์ฌ์ฉ์๊ฐ ์์ก๋ง ํ์ธํ๋ ค๋ ๊ฒฝ์ฐ, ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์ ์ฌ์ฉํ๋ฉด ORM์ด ๋ฒ์ ๊ด๋ฆฌ๋ ๋ฝํน ๋ฉ์ปค๋์ฆ์ ์ ์ฉํ์ง ์์๋ ๋๋ฏ๋ก, ์๋ต ์๋๊ฐ ํฅ์๋ ์ ์์ต๋๋ค.
์บ์ฑ ํจ์จ์ฑ:
ORM ํ๋ ์์ํฌ๋ ์ข ์ข ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ์ฌ, ๋์ผํ ์ฟผ๋ฆฌ์ ๋ํด ๋น ๋ฅธ ์๋ต ์๊ฐ์ ์ ๊ณตํฉ๋๋ค. ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์์๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด ์๊ธฐ ๋๋ฌธ์, ์บ์๋ ๋ฐ์ดํฐ์ ์ ํจ์ฑ์ ๋ํ ์ฐ๋ ค๊ฐ ์ค์ด๋ญ๋๋ค.
์: ๋ด์ค ์น์ฌ์ดํธ์์, ์ฌ์ฉ์๊ฐ ํน์ ์นดํ ๊ณ ๋ฆฌ์ ๋ด์ค ๋ชฉ๋ก์ ์กฐํํ๋ ๊ฒฝ์ฐ, ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์ ์ฌ์ฉํ๋ฉด ORM ํ๋ ์์ํฌ๋ ์ด์ ์ ์กฐํ๋ ๊ฒฐ๊ณผ๋ฅผ ์บ์์์ ๋น ๋ฅด๊ฒ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์ผ๊ด์ฑ ์ ์ง:
์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์ ์ค์๋ก ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ๋ฐฉ์งํฉ๋๋ค. ์๋์น ์๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ์ฑ๋ฅ ๋ฌธ์ ๋ฟ๋ง ์๋๋ผ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๋ฌธ์ ๋ฅผ ์ผ๊ธฐํ ์ ์์ต๋๋ค.
์: ๋ณ์ ์์คํ ์์, ํ์์ ๋ณ๋ ฅ์ ํ์ธํ๋ ๊ฒฝ์ฐ, ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์ ์ฌ์ฉํ๋ฉด, ์ค์๋ก ํ์ ์ ๋ณด๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
Rollback rules (๋กค๋ฐฑ ๊ท์น):
๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐํ์ ์์ธ(
RuntimeException
๋ฐ ๊ทธ ํ์ ์์ธ)๊ฐ ๋ฐ์ํ๋ฉด ๋กค๋ฐฑ์ ์ํํฉ๋๋คrollbackFor
์ด ์์ฑ์ ์ฌ์ฉํ๋ฉด ํน์ ์์ธ๊ฐ ๋ฐ์ํ์ ๋ ํธ๋์ญ์ ์ ๋กค๋ฐฑํ๋ ๊ท์น์ ์ง์ ํ ์ ์์ต๋๋ค.
@Transactional(rollbackFor = InsufficientBalanceException.class) public void transferMoney() { // InsufficientBalanceException์ด ๋ฐ์ํ๋ฉด ํธ๋์ญ์ ์ ๋กค๋ฐฑ๋ฉ๋๋ค. }
noRollbackFor
์ด ์์ฑ์ ์ง์ ๋ ์์ธ ์ ํ์ ๋ํ ๋กค๋ฐฑ์ ๋ฐฉ์งํฉ๋๋ค. ์ฆ, ํด๋น ์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ํธ๋์ญ์ ์ ๋กค๋ฐฑ๋์ง ์์ต๋๋ค.
@Transactional(noRollbackFor = BusinessException.class) public void businessOperation() { // ... // BusinessException์ด ๋ฐ์ํด๋ ํธ๋์ญ์ ์ ๋กค๋ฐฑ๋์ง ์์ต๋๋ค. }
AOP (๊ด์ ์งํฅ ํ๋ก๊ทธ๋๋ฐ):
๋ด๋ถ ๋ฉ์๋ ํธ์ถ์์๋ **
@Transactional
**์ด ์ ๋๋ก ๋์ํ์ง ์๋ ๋ฌธ์ ๋ Spring์ ํ๋ก์ ๋ฐฉ์ ๋๋ฌธ์ ๋๋ค. ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ๋ฉ์๋ ํธ์ถ์ ์ธ๋ถ ๋น์ ํตํด ๊ฐ์ ์ ์ผ๋ก ์ํํ๊ฑฐ๋, ํ๋ก๊ทธ๋จ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
Last updated
Was this helpful?