๐ฑ Spring @Transactional์ ์ ํ ์์ฑ ์ดํด์ ํ์ฉ ๐

์๋ ํ์ธ์, ์ฌ๋ฌ๋ถ! ์ค๋์ Spring Framework์ ํต์ฌ ๊ธฐ๋ฅ ์ค ํ๋์ธ @Transactional ์ด๋ ธํ ์ด์ ๊ณผ ๊ทธ ์ ํ ์์ฑ์ ๋ํด ๊น์ด ํํค์ณ๋ณผ ๊ฑฐ์์. ์ด ์ฃผ์ , ์ข ์ด๋ ต๊ฒ ๋ค๋ฆฌ์ฃ ? ใ ใ ใ ๊ฑฑ์ ๋ง์ธ์! ์ ๊ฐ ์ฝ๊ณ ์ฌ๋ฏธ์๊ฒ ์ค๋ช ํด๋๋ฆด๊ฒ์. ๋ง์น ์นดํก์ผ๋ก ์๋ค ๋ ๋ ๊ฒ์ฒ๋ผ์! ๐
์ฐ๋ฆฌ๊ฐ ์ด ์ฃผ์ ๋ฅผ ์ดํดํ๋ ๊ฑด ์ ๋ง ์ค์ํด์. ์๋๊ณ ์? ํธ๋์ญ์ ๊ด๋ฆฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ค๋ฃจ๋ ๋ชจ๋ ๊ฐ๋ฐ์์๊ฒ ํ์์ ์ธ ์คํฌ์ด๊ฑฐ๋ ์. ํนํ Java ๊ฐ๋ฐ์๋ผ๋ฉด ๋๋์ฑ! ์ด ์ง์์ ์ฌ๋ฌ๋ถ์ ๊ฐ๋ฐ ์ค๋ ฅ์ ํ ๋จ๊ณ ์ ๊ทธ๋ ์ด๋์์ผ์ค ๊ฑฐ์์. ๋ง์น ์ฌ๋ฅ๋ท์์ ์๋ก์ด ์ฌ๋ฅ์ ์ต๋ํ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์ฃ ! ๐
๐ก ๊ฟํ: ์ด ๊ธ์ ๋๊น์ง ์ฝ๊ณ ๋๋ฉด, ์ฌ๋ฌ๋ถ๋ @Transactional ์ ๋ฌธ๊ฐ๊ฐ ๋ ์ ์์ด์! ์ฌ๋ฅ๋ท์์ Java ๊ฐ๋ฐ ๊ด๋ จ ์ฌ๋ฅ์ ๊ณต์ ํ ๋ ์ด ์ง์์ ํ์ฉํ๋ฉด ๋๋ฐ๋ ๊ฑธ์? ใ ใ
์, ๊ทธ๋ผ ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์์ํด๋ณผ๊น์? ์ค๋น๋์ จ๋์? ๊ณ ๊ณ ์ฝ~! ๐๐จ
๐ญ ํธ๋์ญ์ ์ด ๋ญ๊ธธ๋? ๊ธฐ์ด๋ถํฐ ํํํ!
์ฐ์ , ํธ๋์ญ์ ์ด ๋ญ์ง๋ถํฐ ์์๋ณผ๊น์? ํธ๋์ญ์ ์ ๋ญ๊ฐ ์ด๋ ค์ ๋ณด์ด๋ ๋จ์ด์ง๋ง, ์ฌ์ค ์ฐ๋ฆฌ ์ผ์์์๋ ์์ฃผ ๋ณผ ์ ์์ด์.
์๋ฅผ ๋ค์ด๋ณผ๊ฒ์. ์ฌ๋ฌ๋ถ์ด ํธ์์ ์์ ๋ผ๋ฉด์ ์ฌ๋ ์ํฉ์ ์์ํด๋ณด์ธ์. ๐
- ๋ผ๋ฉด์ ๊ณ ๋ฅธ๋ค. ๐ค
- ๊ณ์ฐ๋๋ก ๊ฐ๋ค. ๐ถโโ๏ธ
- ๋์ ์ง๋ถํ๋ค. ๐ฐ
- ์์์ฆ์ ๋ฐ๋๋ค. ๐งพ
์ด ์ ์ฒด ๊ณผ์ ์ด ๋ฐ๋ก ํ๋์ 'ํธ๋์ญ์ '์ด์์. ์ด ๊ณผ์ ์ค ์ด๋ ํ๋๋ผ๋ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์๋ฅผ ๋ค์ด, ๋์ด ๋ถ์กฑํ๋ค๊ฑฐ๋ ๋ผ๋ฉด์ด ํ์ ์ด๋ผ๋ฉด? ๊ทธ๋ผ ์ฒ์๋ถํฐ ๋ค์ ์์ํด์ผ๊ฒ ์ฃ . ์ด๊ฑธ ํ๋ก๊ทธ๋๋ฐ์์๋ '๋กค๋ฐฑ(Rollback)'์ด๋ผ๊ณ ํด์.
๐ ์ฌ๋ฏธ์๋ ์ฌ์ค: ํธ๋์ญ์ ์ด๋ผ๋ ๊ฐ๋ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฟ๋ง ์๋๋ผ ์ฐ๋ฆฌ ์ผ์ ๊ณณ๊ณณ์ ์จ์ด์์ด์. ์ฌ๋ฅ๋ท์์ ์ฌ๋ฅ์ ์ฌ๊ณ ํ๋ ๊ณผ์ ๋ ์ผ์ข ์ ํธ๋์ญ์ ์ด๋ผ๊ณ ๋ณผ ์ ์์ฃ !
์, ์ด์ ํ๋ก๊ทธ๋๋ฐ์์์ ํธ๋์ญ์ ์ผ๋ก ๋์์๋ณผ๊น์?
ํ๋ก๊ทธ๋๋ฐ์์ ํธ๋์ญ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํ๋ฅผ ๋ณํ์ํค๊ธฐ ์ํด ์ํํ๋ ์์ ์ ๋จ์๋ฅผ ๋งํด์. ์ฝ๊ฒ ๋งํด, ์ฌ๋ฌ ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ์ฐ์ ํ๋์ ๋ฌถ์์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฑฐ์ฃ .
ํธ๋์ญ์ ์ ํน์ฑ์ ACID๋ผ๊ณ ๋ถ๋ฌ์. ์ด๊ฒ ๋ญ์ง ์์๋ณผ๊น์?
- ์์์ฑ(Atomicity): ํธ๋์ญ์ ์ ๋ชจ๋ ์ฐ์ฐ์ด ์์ ํ ์ํ๋๊ฑฐ๋, ์๋๋ฉด ์ ํ ์ํ๋์ง ์์์ผ ํด์. ์ค๊ฐ์ ๋ฉ์ถ๋ฉด ์ ๋ผ์!
- ์ผ๊ด์ฑ(Consistency): ํธ๋์ญ์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ผ๊ด๋ ์ํ๋ฅผ ์ ์งํด์ผ ํด์.
- ๊ฒฉ๋ฆฌ์ฑ(Isolation): ๋์์ ์คํ๋๋ ํธ๋์ญ์ ๋ค์ด ์๋ก ์ํฅ์ ๋ฏธ์น์ง ์๋๋ก ๊ฒฉ๋ฆฌ๋์ด์ผ ํด์.
- ์ง์์ฑ(Durability): ํธ๋์ญ์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋ ์๊ตฌ์ ์ผ๋ก ๋ฐ์๋์ด์ผ ํด์.
์ด๋ฐ ํน์ฑ๋ค ๋๋ฌธ์ ํธ๋์ญ์ ์ ๋ฐ์ดํฐ์ ์์ ์ฑ๊ณผ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ๋งค์ฐ ์ค์ํ ์ญํ ์ ํด์. ๋ง์น ์ฌ๋ฅ๋ท์์ ๊ฑฐ๋์ ์์ ์ฑ์ ๋ณด์ฅํ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์ฃ ! ๐
์ด์ ํธ๋์ญ์ ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์์์ผ๋, Spring์์ ์ด๋ป๊ฒ ์ด๋ฅผ ๊ด๋ฆฌํ๋์ง ์์๋ณผ๊น์? ๊ทธ ํต์ฌ์ ๋ฐ๋ก @Transactional ์ด๋ ธํ ์ด์ ์ด ์๋ต๋๋ค! ๐ฏ
๐ @Transactional ์ด๋ ธํ ์ด์ : ํธ๋์ญ์ ์ ๋ง๋ฒ์ฌ
์, ์ด์ ์ฐ๋ฆฌ์ ์ฃผ์ธ๊ณต @Transactional ์ด๋ ธํ ์ด์ ์ ์๊ฐํ ์๊ฐ์ด์์! ์ด ๋ ์, ์ ๋ง ๋๋จํ๋ต๋๋ค. ๋ง์น ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ์ฌ๋ฅ์ ๋น๋๊ฒ ํด์ฃผ๋ ํ๋ซํผ์ฒ๋ผ, @Transactional์ ์ฌ๋ฌ๋ถ์ ์ฝ๋๋ฅผ ๋น๋๊ฒ ํด์ค ๊ฑฐ์์! โจ
@Transactional์ Spring Framework์์ ์ ๊ณตํ๋ ์ด๋ ธํ ์ด์ ์ผ๋ก, ๋ฉ์๋๋ ํด๋์ค์ ํธ๋์ญ์ ๊ธฐ๋ฅ์ ๋ถ์ฌํด์ค๋๋ค. ์ด ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ฉด, ๋ณต์กํ ํธ๋์ญ์ ๊ด๋ฆฌ ์ฝ๋๋ฅผ ์ง์ ์์ฑํ์ง ์์๋ ๋ผ์. ์ ๋ง ํธ๋ฆฌํ์ฃ ?
๐ก ๊ฟํ: @Transactional์ ์ฌ์ฉํ๋ฉด ์ฝ๋๊ฐ ํจ์ฌ ๊น๋ํด์ง๊ณ ์ ์ง๋ณด์๋ ์ฌ์์ ธ์. ๋ง์น ์ฌ๋ฅ๋ท์์ ๊ฑฐ๋๋ฅผ ํ ๋ ํ๋ซํผ์ด ๋ชจ๋ ๋ณต์กํ ๊ณผ์ ์ ๋์ ์ฒ๋ฆฌํด์ฃผ๋ ๊ฒ๊ณผ ๊ฐ์ฃ !
๊ทธ๋ผ ์ด @Transactional์ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ๊ฐ๋จํ ์์ ๋ก ์ดํด๋ณผ๊น์?
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Transactional
public void createUser(User user) {
// ์ฌ์ฉ์ ์์ฑ ๋ก์ง
}
}
์ ์ฝ๋์์ createUser ๋ฉ์๋์ @Transactional ์ด๋ ธํ ์ด์ ์ ๋ถ์์ด์. ์ด๋ ๊ฒ ํ๋ฉด ์ด ๋ฉ์๋ ๋ด์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ์ฐ์ด ํ๋์ ํธ๋์ญ์ ์ผ๋ก ์ฒ๋ฆฌ๋ผ์. ๋ง์ฝ ๋ฉ์๋ ์คํ ์ค์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ชจ๋ ๋ณ๊ฒฝ์ฌํญ์ด ๋กค๋ฐฑ๋ฉ๋๋ค. ์ฉ์ง ์๋์? ๐
ํ์ง๋ง ์ฌ๊ธฐ์ ๋์ด ์๋์์! @Transactional ์ด๋ ธํ ์ด์ ์ ๋ค์ํ ์์ฑ์ ๊ฐ์ง๊ณ ์์ด์. ์ด ์์ฑ๋ค์ ์ด์ฉํ๋ฉด ํธ๋์ญ์ ์ ๋์์ ๋ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์๋ต๋๋ค.
๊ทธ ์ค์์๋ ํนํ ์ค์ํ ๊ฒ ๋ฐ๋ก '์ ํ ์์ฑ(Propagation)'์ด์์. ์ด๊ฒ ๋ญ์ง ๊ถ๊ธํ์์ฃ ? ๋ค์ ์น์ ์์ ์์ธํ ์์๋ณด๋๋ก ํด์! ๐
์, ์ด์ @Transactional ์ด๋ ธํ ์ด์ ์ ๊ธฐ๋ณธ์ ์์์ด์. ํ์ง๋ง ์ด๊ฑด ๋น์ฐ์ ์ผ๊ฐ์ผ ๋ฟ์ด์์! ๋ค์ ์น์ ์์๋ ์ด ์ด๋ ธํ ์ด์ ์ ์ง์ง ๋งค๋ ฅ, ์ ํ ์์ฑ์ ๋ํด ์์๋ณผ ๊ฑฐ์์. ๊ธฐ๋๋์ง ์๋์? ์ ๋ ๋๋ฌด ์ ๋์! ๐คฉ
๐ ์ ํ ์์ฑ: ํธ๋์ญ์ ์ ๋น๋ฐ ๋ ์ํผ
์, ์ด์ ์ฐ๋ฆฌ์ ๋ฉ์ธ ๋์, ์ ํ ์์ฑ(Propagation)์ ๋ํด ์์๋ณผ ์๊ฐ์ด์์! ์ด๊ฑฐ ์ง์ง ๋๋ฐ์ด์์. ๋ง์น ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ์ฌ๋ฅ์ ๋ค์ํ ๋ฐฉ์์ผ๋ก ํ์ฉํ ์ ์๋ ๊ฒ์ฒ๋ผ, ์ ํ ์์ฑ์ ์ด์ฉํ๋ฉด ํธ๋์ญ์ ์ ๋ค์ํ ๋ฐฉ์์ผ๋ก ์ ์ดํ ์ ์์ด์. ๐
์ ํ ์์ฑ์ ํธ๋์ญ์ ์ ๊ฒฝ๊ณ๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋งํด์. ์ฝ๊ฒ ๋งํด, ๊ธฐ์กด์ ํธ๋์ญ์ ์ด ์งํ ์ค์ผ ๋ ์๋ก์ด ํธ๋์ญ์ ์ ์์ํ๋ ค๊ณ ํ ๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง๋ฅผ ๊ฒฐ์ ํ๋ ๊ฑฐ์ฃ .
๐ ์ฌ๋ฏธ์๋ ์ฌ์ค: ์ ํ ์์ฑ์ ๋ง์น ์๋ฆฌ ๋ ์ํผ์ ๊ฐ์์. ๊ฐ์ ์ฌ๋ฃ(ํธ๋์ญ์ )๋ก๋ ์ด๋ป๊ฒ ์กฐ๋ฆฌ(์ ํ)ํ๋๋์ ๋ฐ๋ผ ์ ํ ๋ค๋ฅธ ๋ง(๊ฒฐ๊ณผ)์ด ๋์ค์ฃ !
Spring์์๋ 7๊ฐ์ง์ ์ ํ ์์ฑ์ ์ ๊ณตํด์. ๊ฐ๊ฐ์ ์์ฑ์ ํ๋์ฉ ์ดํด๋ณผ๊น์?
- REQUIRED (๊ธฐ๋ณธ๊ฐ): ํ์ฌ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ๊ทธ๊ฑธ ์ฌ์ฉํ๊ณ , ์์ผ๋ฉด ์๋ก ๋ง๋ค์ด์. ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ์ต์ ์ด์์.
- SUPPORTS: ํ์ฌ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ๊ทธ๊ฑธ ์ฌ์ฉํ๊ณ , ์์ด๋ ๊ด์ฐฎ์์. ํธ๋์ญ์ ์์ด๋ ์คํ ๊ฐ๋ฅํ ๋ฉ์๋์ ์ฌ์ฉํด์.
- MANDATORY: ํ์ฌ ํธ๋์ญ์ ์ด ๋ฐ๋์ ์์ด์ผ ํด์. ์์ผ๋ฉด ์์ธ๋ฅผ ๋ฐ์์์ผ์.
- REQUIRES_NEW: ํญ์ ์๋ก์ด ํธ๋์ญ์ ์ ์์ํด์. ๊ธฐ์กด ํธ๋์ญ์ ์ด ์๋ค๋ฉด ์ ์ ์ค๋จํ๊ณ ์ ํธ๋์ญ์ ์ ์คํํด์.
- NOT_SUPPORTED: ํธ๋์ญ์ ์์ด ์คํํด์. ํ์ฌ ํธ๋์ญ์ ์ด ์๋ค๋ฉด ์ ์ ์ค๋จํด์.
- NEVER: ํธ๋์ญ์ ์์ด ์คํํด์. ํ์ฌ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ์์ธ๋ฅผ ๋ฐ์์์ผ์.
- NESTED: ํ์ฌ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ์ค์ฒฉ ํธ๋์ญ์ ์ ์์ํด์. ์์ผ๋ฉด REQUIRED์ฒ๋ผ ๋์ํด์.
์์ฐ! ์ด๋ ๊ฒ ๋ค์ํ ์ต์ ์ด ์๋ค๋ ๋๋์ง ์๋์? ๊ฐ๊ฐ์ ์ํฉ์ ๋ง๋ ์ ํ ์์ฑ์ ์ ํํ๋ฉด ํธ๋์ญ์ ์ ๋์ฑ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ด์. ๐
์, ์ด์ ๊ฐ๊ฐ์ ์ ํ ์์ฑ์ ๋ํด ๋ ์์ธํ ์์๋ณผ๊น์? ์์ ์ฝ๋์ ํจ๊ป ์ค๋ช ํด๋๋ฆด๊ฒ์. ์ค๋น๋์ จ๋์? ๊ณ ๊ณ ์ฝ~! ๐
1. REQUIRED (๊ธฐ๋ณธ๊ฐ)
REQUIRED๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ด๊ณ ๋ง์ด ์ฌ์ฉ๋๋ ์ ํ ์์ฑ์ด์์. ํ์ฌ ์งํ ์ค์ธ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ๊ทธ ํธ๋์ญ์ ์ ์ฌ์ฉํ๊ณ , ์์ผ๋ฉด ์๋ก์ด ํธ๋์ญ์ ์ ์์ํด์.
@Transactional(propagation = Propagation.REQUIRED)
public void createUser(User user) {
userRepository.save(user);
emailService.sendWelcomeEmail(user);
}
์ด ์์ ์์ createUser ๋ฉ์๋๋ ์ฌ์ฉ์๋ฅผ ์ ์ฅํ๊ณ ํ์ ์ด๋ฉ์ผ์ ๋ณด๋ด๋ ๋ ๊ฐ์ง ์์ ์ ์ํํด์. REQUIRED ์์ฑ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์, ์ด ๋ ์์ ์ ํ๋์ ํธ๋์ญ์ ๋ด์์ ์คํ๋ผ์. ๋ง์ฝ ์ด๋ฉ์ผ ์ ์ก ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด, ์ฌ์ฉ์ ์ ์ฅ๋ ๋กค๋ฐฑ๋ฉ๋๋ค.
2. SUPPORTS
SUPPORTS๋ ํ์ฌ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ๊ทธ๊ฑธ ์ฌ์ฉํ๊ณ , ์์ด๋ ๊ด์ฐฎ์์. ํธ๋์ญ์ ์ด ๊ผญ ํ์ํ์ง ์์ ์ฐ์ฐ์ ์ฌ์ฉํ๋ฉด ์ข์์.
@Transactional(propagation = Propagation.SUPPORTS)
public List<user> getAllUsers() {
return userRepository.findAll();
}
</user>
์ด ๋ฉ์๋๋ ๋จ์ํ ๋ชจ๋ ์ฌ์ฉ์๋ฅผ ์กฐํํ๋ ์์ ์ด์์. ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ธฐ ๋๋ฌธ์ ํธ๋์ญ์ ์ด ๊ผญ ํ์ํ์ง ์์ฃ . ํ์ง๋ง ๋ค๋ฅธ ํธ๋์ญ์ ๋ด์์ ํธ์ถ๋๋ค๋ฉด ๊ทธ ํธ๋์ญ์ ์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์์ด์.
3. MANDATORY
MANDATORY๋ ํ์ฌ ์งํ ์ค์ธ ํธ๋์ญ์ ์ด ๋ฐ๋์ ์์ด์ผ ํด์. ์์ผ๋ฉด ์์ธ๋ฅผ ๋ฐ์์์ผ์.
@Transactional(propagation = Propagation.MANDATORY)
public void updateUserPassword(Long userId, String newPassword) {
User user = userRepository.findById(userId).orElseThrow();
user.setPassword(newPassword);
userRepository.save(user);
}
์ด ๋ฉ์๋๋ ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๋ ์ค์ํ ์์ ์ ์ํํด์. MANDATORY๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ, ์ด ๋ฉ์๋๊ฐ ๋ฐ๋์ ํธ๋์ญ์ ๋ด์์ ํธ์ถ๋๋๋ก ๊ฐ์ ํ ์ ์์ด์. ๋ง์ฝ ํธ๋์ญ์ ์์ด ํธ์ถ๋๋ฉด ์์ธ๊ฐ ๋ฐ์ํด์ ์ค์๋ก ํธ๋์ญ์ ์์ด ๋น๋ฐ๋ฒํธ๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ฃ .
4. REQUIRES_NEW
REQUIRES_NEW๋ ํญ์ ์๋ก์ด ํธ๋์ญ์ ์ ์์ํด์. ๊ธฐ์กด ํธ๋์ญ์ ์ด ์๋ค๋ฉด ์ ์ ์ค๋จํ๊ณ ์ ํธ๋์ญ์ ์ ์คํํด์.
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logUserAction(Long userId, String action) {
UserLog log = new UserLog(userId, action);
logRepository.save(log);
}
์ด ๋ฉ์๋๋ ์ฌ์ฉ์์ ํ๋์ ๋ก๊ทธ๋ก ๊ธฐ๋กํด์. REQUIRES_NEW๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ, ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ฑ๊ณต ์ฌ๋ถ์ ๊ด๊ณ์์ด ๋ก๊ทธ๊ฐ ํญ์ ์ ์ฅ๋๋๋ก ํ ์ ์์ด์. ๋ฉ์ธ ํธ๋์ญ์ ์ด ์คํจํด๋ ๋ก๊ทธ๋ ๋จ๋ ๊ฑฐ์ฃ !
5. NOT_SUPPORTED
NOT_SUPPORTED๋ ํธ๋์ญ์ ์์ด ์คํํด์. ํ์ฌ ํธ๋์ญ์ ์ด ์๋ค๋ฉด ์ ์ ์ค๋จํด์.
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public int countUsers() {
return userRepository.count();
}
์ด ๋ฉ์๋๋ ๋จ์ํ ์ฌ์ฉ์ ์๋ฅผ ์ธ๋ ์์ ์ ์ํํด์. ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋น ๋ฅด๊ฒ ์คํ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ์ NOT_SUPPORTED๋ฅผ ์ฌ์ฉํ ์ ์์ด์. ํธ๋์ญ์ ์ค๋ฒํค๋๋ฅผ ์ค์ผ ์ ์์ฃ .
6. NEVER
NEVER๋ ํธ๋์ญ์ ์์ด ์คํํด์. ํ์ฌ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ์์ธ๋ฅผ ๋ฐ์์์ผ์.
@Transactional(propagation = Propagation.NEVER)
public void sendPromotionalEmail(String email) {
// ํ๋ก๋ชจ์
์ด๋ฉ์ผ ์ ์ก ๋ก์ง
}
์ด ๋ฉ์๋๋ ํ๋ก๋ชจ์ ์ด๋ฉ์ผ์ ์ ์กํ๋ ์์ ์ ์ํํด์. ์ด๋ฉ์ผ ์ ์ก์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ๊ณผ ๋ฌด๊ดํ๋ฏ๋ก, ํธ๋์ญ์ ์ด ํ์ ์์ด์. NEVER๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ, ์ค์๋ก ํธ๋์ญ์ ๋ด์์ ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ด์.
7. NESTED
NESTED๋ ํ์ฌ ํธ๋์ญ์ ์ด ์์ผ๋ฉด ์ค์ฒฉ ํธ๋์ญ์ ์ ์์ํด์. ์์ผ๋ฉด REQUIRED์ฒ๋ผ ๋์ํด์.
@Transactional(propagation = Propagation.NESTED)
public void createUserWithBonus(User user, Bonus bonus) {
userRepository.save(user);
bonusRepository.save(bonus);
}
์ด ๋ฉ์๋๋ ์ฌ์ฉ์๋ฅผ ์์ฑํ๊ณ ๋ณด๋์ค๋ฅผ ์ง๊ธํ๋ ์์ ์ ์ํํด์. NESTED๋ฅผ ์ฌ์ฉํ๋ฉด, ์ธ๋ถ ํธ๋์ญ์ ์ด ์์ ๊ฒฝ์ฐ ์ค์ฒฉ ํธ๋์ญ์ ์ผ๋ก ์คํ๋ผ์. ๋ง์ฝ ๋ณด๋์ค ์ง๊ธ์ ์คํจํด๋ ์ฌ์ฉ์ ์์ฑ์ ๊ทธ๋๋ก ์ ์ง๋ ์ ์์ด์. ํ์ง๋ง ์ธ๋ถ ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋๋ฉด ์ด ๋ฉ์๋์ ์์ ๋ ๋ชจ๋ ๋กค๋ฐฑ๋ผ์.
๐ก ๊ฟํ: ์ ํ ์์ฑ์ ์ ํ์ฉํ๋ฉด ๋ณต์กํ ๋น์ฆ๋์ค ๋ก์ง์์๋ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ฉด์ ์ ์ฐํ ํธ๋์ญ์ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํด์. ๋ง์น ์ฌ๋ฅ๋ท์์ ๋ค์ํ ์ฌ๋ฅ์ ์กฐํฉํด ์๋ก์ด ๊ฐ์น๋ฅผ ๋ง๋ค์ด๋ด๋ ๊ฒ์ฒ๋ผ์!
์์ฐ! ์ด๋ ๊ฒ ๋ค์ํ ์ ํ ์์ฑ์ด ์๋ค๋ ์ ๋ง ๋๋จํ์ง ์๋์? ๊ฐ๊ฐ์ ์ํฉ์ ๋ง๋ ์ ํ ์์ฑ์ ์ ํํ๋ฉด ํธ๋์ญ์ ์ ๋์ฑ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ด์. ๐
ํ์ง๋ง ์ฌ๊ธฐ์ ๋์ด ์๋์์! ์ ํ ์์ฑ์ ์ค์ ๋ก ์ด๋ป๊ฒ ํ์ฉํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ฃผ์ํด์ผ ํ ์ ์ ๋ฌด์์ธ์ง ๋ ์์ธํ ์์๋ณผ๊น์? ๋ค์ ์น์ ์์ ๊ณ์๋ฉ๋๋ค! ๐
๐ญ ์ ํ ์์ฑ์ ์ค์ ํ์ฉ๊ณผ ์ฃผ์์ฌํญ
์, ์ด์ ์ฐ๋ฆฌ๋ ์ ํ ์์ฑ์ ๊ธฐ๋ณธ์ ์์์ด์. ํ์ง๋ง ์ค์ ๋ก ์ด๊ฑธ ์ด๋ป๊ฒ ํ์ฉํ๊ณ , ์ด๋ค ์ ์ ์ฃผ์ํด์ผ ํ ๊น์? ๋ง์น ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ์ฌ๋ฅ์ ํจ๊ณผ์ ์ผ๋ก ์ ๋ณด์ด๊ธฐ ์ํด ์ ๋ต์ ์ธ์ฐ๋ ๊ฒ์ฒ๋ผ, ์ ํ ์์ฑ๋ ์ ๋ต์ ์ผ๋ก ์ฌ์ฉํด์ผ ํด์! ๐
1. ์ ํ ์์ฑ์ ์ค์ ํ์ฉ
์ ํ ์์ฑ์ ๋น์ฆ๋์ค ๋ก์ง์ ํน์ฑ์ ๋ฐ๋ผ ์ ์ ํ ์ ํํด์ผ ํด์. ๋ช ๊ฐ์ง ์ค์ ์์๋ฅผ ํตํด ์ดํด๋ณผ๊น์?
์์ 1: ์ฃผ๋ฌธ ์ฒ๋ฆฌ ์์คํ
@Service
public class OrderService {
@Autowired
private ProductService productService;
@Autowired
private PaymentService paymentService;
@Transactional
public void processOrder(Order order) {
// ์ฃผ๋ฌธ ์ ์ฅ
orderRepository.save(order);
// ์ฌ๊ณ ๊ฐ์
productService.decreaseStock(order.getProductId(), order.getQuantity());
// ๊ฒฐ์ ์ฒ๋ฆฌ
paymentService.processPayment(order.getPaymentDetails());
}
}
@Service
public class ProductService {
@Transactional(propagation = Propagation.REQUIRED)
public void decreaseStock(Long productId, int quantity) {
// ์ฌ๊ณ ๊ฐ์ ๋ก์ง
}
}
@Service
public class PaymentService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processPayment(PaymentDetails details) {
// ๊ฒฐ์ ์ฒ๋ฆฌ ๋ก์ง
}
}
์ด ์์์์ ์ฃผ๋ฌธ ์ฒ๋ฆฌ๋ ์ธ ๋จ๊ณ๋ก ์ด๋ฃจ์ด์ ธ์. ์ฃผ๋ฌธ ์ ์ฅ, ์ฌ๊ณ ๊ฐ์, ๊ฒฐ์ ์ฒ๋ฆฌ. ProductService์ decreaseStock ๋ฉ์๋๋ REQUIRED๋ฅผ ์ฌ์ฉํด ์ฃผ๋ฌธ ์ฒ๋ฆฌ์ ํธ๋์ญ์ ์ ์ฐธ์ฌํด์. ํ์ง๋ง PaymentService์ processPayment๋ REQUIRES_NEW๋ฅผ ์ฌ์ฉํด ๋ณ๋์ ํธ๋์ญ์ ์ผ๋ก ์ฒ๋ฆฌ๋ผ์. ์ ๊ทธ๋ด๊น์?
๋ง์ฝ ๊ฒฐ์ ์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํด๋ ์ฃผ๋ฌธ ์ ๋ณด์ ์ฌ๊ณ ๊ฐ์๋ ๊ทธ๋๋ก ์ ์ง๋์ด์ผ ํ ์ ์์ด์. ๊ฒฐ์ ๋ ๋์ค์ ๋ค์ ์๋ํ ์ ์์ง๋ง, ์ฌ๊ณ ๋ ์ฆ์ ๋ฐ์๋์ด์ผ ํ๋๊น์. ์ด๋ฐ ๊ฒฝ์ฐ REQUIRES_NEW๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฒฐ์ ์คํจ ์์๋ ์ฃผ๋ฌธ๊ณผ ์ฌ๊ณ ์ ๋ณด๋ ์ปค๋ฐ๋ ์ ์์ด์.
์์ 2: ๋ก๊น ์์คํ
@Service
public class UserService {
@Autowired
private LoggingService loggingService;
@Transactional
public void registerUser(User user) {
// ์ฌ์ฉ์ ๋ฑ๋ก ๋ก์ง
userRepository.save(user);
// ๋ก๊ทธ ๊ธฐ๋ก
loggingService.logUserRegistration(user);
}
}
@Service
public class LoggingService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logUserRegistration(User user) {
// ๋ก๊ทธ ์ ์ฅ ๋ก์ง
}
}
์ด ์์์์ ๋ก๊น ์๋น์ค๋ REQUIRES_NEW๋ฅผ ์ฌ์ฉํด์. ์ ๊ทธ๋ด๊น์? ์ฌ์ฉ์ ๋ฑ๋ก์ด ์คํจํ๋๋ผ๋ ๋ก๊ทธ๋ ๋จ์์์ด์ผ ํ๊ธฐ ๋๋ฌธ์ด์์. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ์ฉ์ ๋ฑ๋ก ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋์ด๋ ๋ก๊ทธ๋ ๊ทธ๋๋ก ์ ์ฅ๋ ์ ์์ด์.
2. ์ฃผ์์ฌํญ
์ ํ ์์ฑ์ ์ฌ์ฉํ ๋๋ ๋ช ๊ฐ์ง ์ฃผ์ํด์ผ ํ ์ ์ด ์์ด์. ๋ง์น ์ฌ๋ฅ๋ท์์ ์ฌ๋ฅ์ ์ ๋ณด์ผ ๋ ์ฃผ์ํด์ผ ํ ์ ์ด ์๋ ๊ฒ์ฒ๋ผ ๋ง์ด์ฃ !
- ์ฑ๋ฅ ๊ณ ๋ ค: REQUIRES_NEW๋ NESTED๋ฅผ ๊ณผ๋ํ๊ฒ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ๋ง์ด ์ฌ์ฉํ๊ฒ ๋์ด ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ด์.
- ๋ฐ๋๋ฝ ์ฃผ์: ์ฌ๋ฌ ํธ๋์ญ์ ์ด ์๋ก ๋ค๋ฅธ ์์๋ก ๋ฆฌ์์ค๋ฅผ ์์ฒญํ๋ฉด ๋ฐ๋๋ฝ์ด ๋ฐ์ํ ์ ์์ด์. ํนํ REQUIRES_NEW๋ฅผ ์ฌ์ฉํ ๋ ์ฃผ์ํด์ผ ํด์.
- ๋กค๋ฐฑ ๋ฒ์ ์ดํด: REQUIRED๋ฅผ ์ฌ์ฉํ๋ฉด ํธ์ถํ ๋ฉ์๋์ ํธ๋์ญ์ ์ ํฌํจ๋๋ฏ๋ก, ํธ์ถ๋ ๋ฉ์๋์์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ํธ์ถํ ๋ฉ์๋์ ์์ ๋ ๋กค๋ฐฑ๋ ์ ์์ด์.
- ํ๋ก์ ํ๊ณ ์ดํด: @Transactional์ ํ๋ก์๋ฅผ ํตํด ๋์ํด์. ๊ฐ์ ํด๋์ค ๋ด์ ๋ฉ์๋ ํธ์ถ์๋ ์ ์ฉ๋์ง ์์ ์ ์์ผ๋ ์ฃผ์ํด์ผ ํด์.
๐ก ๊ฟํ: ์ ํ ์์ฑ์ ์ฌ์ฉํ ๋๋ ํญ์ ๋น์ฆ๋์ค ๋ก์ง์ ์ ์ดํดํ๊ณ , ๊ฐ ์ํฉ์ ๊ฐ์ฅ ์ ํฉํ ์์ฑ์ ์ ํํด์ผ ํด์. ๋๋ก๋ ๊ฐ๋จํ REQUIRED๊ฐ ๊ฐ์ฅ ์ข์ ์ ํ์ผ ์ ์์ด์!
3. ์ค์ ์ฌ์ฉ ์ฌ๋ก
์, ์ด์ ์ค์ ํ๋ก์ ํธ์์ ์ด๋ป๊ฒ ์ ํ ์์ฑ์ ํ์ฉํ ์ ์๋์ง ์ข ๋ ๋ณต์กํ ์์ ๋ฅผ ํตํด ์ดํด๋ณผ๊น์?
@Service
public class ShoppingService {
@Autowired
private OrderService orderService;
@Autowired
private InventoryService inventoryService;
@Autowired
private NotificationService notificationService;
@Transactional
public void processPurchase(Purchase purchase) {
// ์ฃผ๋ฌธ ์์ฑ
Order order = orderService.createOrder(purchase);
// ์ฌ๊ณ ํ์ธ ๋ฐ ๊ฐ์
inventoryService.updateInventory(purchase.getItems());
// ๊ฒฐ์ ์ฒ๋ฆฌ
paymentService.processPayment(purchase.getPaymentDetails());
// ์ฃผ๋ฌธ ํ์ธ ์ด๋ฉ์ผ ๋ฐ์ก
notificationService.sendOrderConfirmation(order);
}
}
@Service
public class OrderService {
@Transactional(propagation = Propagation.REQUIRED)
public Order createOrder(Purchase purchase) {
// ์ฃผ๋ฌธ ์์ฑ ๋ก์ง
}
}
@Service
public class InventoryService {
@Transactional(propagation = Propagation.REQUIRED)
public void updateInventory(List<item> items) {
// ์ฌ๊ณ ์
๋ฐ์ดํธ ๋ก์ง
}
}
@Service
public class PaymentService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processPayment(PaymentDetails details) {
// ๊ฒฐ์ ์ฒ๋ฆฌ ๋ก์ง
}
}
@Service
public class NotificationService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void sendOrderConfirmation(Order order) {
// ์ด๋ฉ์ผ ๋ฐ์ก ๋ก์ง
}
}
</item>
์ด ์์ ์์ ShoppingService์ processPurchase ๋ฉ์๋๋ ์ ์ฒด ๊ตฌ๋งค ํ๋ก์ธ์ค๋ฅผ ๊ด๋ฆฌํด์. OrderService์ InventoryService๋ REQUIRED๋ฅผ ์ฌ์ฉํด ์ฃผ ํธ๋์ญ์ ์ ์ฐธ์ฌํ๊ณ ์์ด์. ์ด๋ ๊ฒ ํ๋ฉด ์ฃผ๋ฌธ ์์ฑ๊ณผ ์ฌ๊ณ ์ ๋ฐ์ดํธ๊ฐ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ์ฒ๋ฆฌ๋์ด ์ผ๊ด์ฑ์ ์ ์งํ ์ ์์ด์.
๋ฐ๋ฉด, PaymentService์ NotificationService๋ REQUIRES_NEW๋ฅผ ์ฌ์ฉํ๊ณ ์์ด์. ์ ๊ทธ๋ด๊น์?
- ๊ฒฐ์ ๋ ๋ณ๋์ ํธ๋์ญ์ ์ผ๋ก ์ฒ๋ฆฌ๋์ด์ผ ํด์. ๋ง์ฝ ์ด๋ฉ์ผ ๋ฐ์ก ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํด๋ ๊ฒฐ์ ๋ ๋กค๋ฐฑ๋๋ฉด ์ ๋๋๊น์.
- ์ด๋ฉ์ผ ๋ฐ์ก๋ ๋ง์ฐฌ๊ฐ์ง์์. ๋ค๋ฅธ ๊ณผ์ ์์ ๋ฌธ์ ๊ฐ ์๊ฒจ๋ ๊ณ ๊ฐ์๊ฒ ์ด๋ฉ์ผ์ ๋ฐ์ก๋์ด์ผ ํด์. ๋์ค์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ์ ๋ณด๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด์์ฃ .
์ด๋ ๊ฒ ์ ํ ์์ฑ์ ์ ์ ํ ํ์ฉํ๋ฉด, ๋ณต์กํ ๋น์ฆ๋์ค ๋ก์ง์์๋ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ฉด์ ์ ์ฐํ ํธ๋์ญ์ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํด์ ธ์. ๐
์์ฐ! ์ด์ ์ ํ ์์ฑ์ ์ค์ ํ์ฉ๋ฒ๊ณผ ์ฃผ์์ฌํญ๊น์ง ์์๋ดค์ด์. ์ด๊ฑธ ์ ํ์ฉํ๋ฉด ์ฌ๋ฌ๋ถ์ Spring ์ ํ๋ฆฌ์ผ์ด์ ์ ๋์ฑ ์์ ์ ์ด๊ณ ํจ์จ์ ์ผ๋ก ๋์ํ ๊ฑฐ์์. ๋ง์น ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ์ฌ๋ฅ์ด ๋น์ ๋ฐํ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์ฃ ! ๐
์, ์ด์ ์ฐ๋ฆฌ์ @Transactional ์ฌํ์ด ๊ฑฐ์ ๋๋๊ฐ๊ณ ์์ด์. ๋ง์ง๋ง์ผ๋ก ์ ์ฒด ๋ด์ฉ์ ์ ๋ฆฌํ๊ณ ๋ช ๊ฐ์ง ์ถ๊ฐ ํ์ ๋๋ฆด๊ฒ์. ์ค๋น๋์ จ๋์? ๋ง์ง๋ง ์คํผํธ ํ๋ฒ ํด๋ณผ๊น์? ๐ช
๐ ์ ๋ฆฌ ๋ฐ ์ถ๊ฐ ํ
์, ์ด์ ์ฐ๋ฆฌ์ @Transactional ์ฌํ์ด ๋๋๊ฐ๊ณ ์์ด์. ์ ๋ง ๊ธด ์ฌ์ ์ด์์ฃ ? ํ์ง๋ง ์ฌ๋ฌ๋ถ์ ์ด์ @Transactional์ ์ ๋ฌธ๊ฐ๊ฐ ๋์์ด์! ๐๐๐
์ฐ๋ฆฌ๊ฐ ๋ฐฐ์ด ๋ด์ฉ์ ๊ฐ๋จํ ์ ๋ฆฌํด๋ณผ๊น์?
- @Transactional์ Spring์์ ํธ๋์ญ์ ์ ๊ด๋ฆฌํ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์์.
- ์ ํ ์์ฑ์ ํตํด ํธ๋์ญ์ ์ ๋์์ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์์ด์.
- REQUIRED, REQUIRES_NEW, NESTED ๋ฑ ๋ค์ํ ์ ํ ์์ฑ์ด ์์ผ๋ฉฐ, ๊ฐ๊ฐ ๋ค๋ฅธ ์ํฉ์์ ์ ์ฉํด์.
- ์ ํ ์์ฑ์ ์ ํ์ฉํ๋ฉด ๋ณต์กํ ๋น์ฆ๋์ค ๋ก์ง์์๋ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ ์งํ ์ ์์ด์.
- ํ์ง๋ง ์ ํ ์์ฑ ์ฌ์ฉ ์ ์ฑ๋ฅ, ๋ฐ๋๋ฝ, ๋กค๋ฐฑ ๋ฒ์ ๋ฑ์ ์ฃผ์ํด์ผ ํด์.
์ด์ ๋ช ๊ฐ์ง ์ถ๊ฐ ํ์ ๋๋ฆด๊ฒ์. ์ด ํ๋ค์ ๊ธฐ์ตํ๋ฉด @Transactional ์ฌ์ฉ ์ ๋์ฑ ๋น๋๋ ๊ฐ๋ฐ์๊ฐ ๋ ์ ์์ ๊ฑฐ์์! โจ
1. ํ ์คํธ๋ ํ์!
ํธ๋์ญ์ ๊ด๋ฆฌ๋ ๋ณต์กํ ์ ์์ด์. ํญ์ ๋ค์ํ ์๋๋ฆฌ์ค์ ๋ํด ์ฒ ์ ํ ํ ์คํธํ์ธ์. ํนํ ๋กค๋ฐฑ ์ํฉ์ ๊ผญ ํ ์คํธํด๋ณด์ธ์.
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShoppingServiceTest {
@Autowired
private ShoppingService shoppingService;
@Test
@Transactional
public void testPurchaseRollback() {
// ํ
์คํธ ๋ก์ง
}
}
2. ๋ก๊น ์ ์น๊ตฌ์์
ํธ๋์ญ์ ๋์์ ๋ก๊น ํ๋ฉด ๋ฌธ์ ํด๊ฒฐ์ ํฐ ๋์์ด ๋ผ์. Spring์ ๋ก๊น ์ค์ ์ ํ์ฉํ์ธ์.
logging.level.org.springframework.transaction=DEBUG
3. ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ํ์ฉํ๊ธฐ
๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์๋ ์ฐ์ฐ์๋ ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ ์ ์ฌ์ฉํ์ธ์. ์ฑ๋ฅ์ด ํฅ์๋ ์ ์์ด์.
@Transactional(readOnly = true)
public List<user> getAllUsers() {
return userRepository.findAll();
}
</user>
4. ํ์์์ ์ค์ ์์ง ๋ง์ธ์
์ฅ์๊ฐ ์คํ๋๋ ํธ๋์ญ์ ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ด์. ์ ์ ํ ํ์์์์ ์ค์ ํ์ธ์.
@Transactional(timeout = 30) // 30์ด ํ ํ์์์
public void longRunningOperation() {
// ์ค๋ ๊ฑธ๋ฆฌ๋ ์์
}
5. ์์ธ ์ฒ๋ฆฌ์ ์ ๊ฒฝ ์ฐ๊ธฐ
์ฒดํฌ ์์ธ์ ์ธ์ฒดํฌ ์์ธ์ ๋ฐ๋ผ ํธ๋์ญ์ ์ ๋กค๋ฐฑ ๋์์ด ๋ฌ๋ผ์ง ์ ์์ด์. ์ด๋ฅผ ์ดํดํ๊ณ ์ ์ ํ ์ฒ๋ฆฌํ์ธ์.
@Transactional(rollbackFor = Exception.class)
public void operationWithCustomRollback() throws Exception {
// ์์
๋ก์ง
}
๐ก ์ต์ข ๊ฟํ: @Transactional์ ๊ฐ๋ ฅํ์ง๋ง, ๊ณผ๋ํ ์ฌ์ฉ์ ํผํ์ธ์. ๋๋ก๋ ๋จ์ํ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ์ ์์ด์. ํญ์ ๋น์ฆ๋์ค ๋ก์ง์ ๋จผ์ ์ดํดํ๊ณ , ๊ทธ์ ๋ง๋ ๊ฐ์ฅ ์ ์ ํ ๋ฐฉ์์ ์ ํํ์ธ์!
์ฌ๋ฌ๋ถ, ์ ๋ง ์๊ณ ํ์ จ์ด์! ์ด์ ์ฌ๋ฌ๋ถ์ @Transactional๊ณผ ์ ํ ์์ฑ์ ์ง์ ํ ๋ง์คํฐ๊ฐ ๋์์ด์. ์ด ์ง์์ ํ์ฉํด ๋์ฑ ์์ ์ ์ด๊ณ ํจ์จ์ ์ธ Spring ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค์ด๋ณด์ธ์. ๋ง์น ์ฌ๋ฅ๋ท์์ ์ฌ๋ฌ๋ถ์ ์ฌ๋ฅ์ผ๋ก ์ธ์์ ๋ ํ์๋กญ๊ฒ ๋ง๋๋ ๊ฒ์ฒ๋ผ ๋ง์ด์์! ๐จโ๐ป๐ฉโ๐ป
์์ผ๋ก์ ๊ฐ๋ฐ ์ฌ์ ์ ํ์ด์ด ํจ๊ปํ๊ธฐ๋ฅผ ๋ฐ๋๊ฒ์. ํ์ดํ ! ๐๐
- ์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์ฌ๋ฅ๋ท์ ์ต์ AI ๊ธฐ์ ๊ณผ ๋ฒ๋ฅ ์ ๊ธฐ๋ฐํ์ฌ ์์ฌ์ ์ง์ ์ฌ์ฐ๊ถ์ ์ ๊ทน์ ์ผ๋ก ๋ณดํธํ๋ฉฐ,
๋ฌด๋จ ์ฌ์ฉ ๋ฐ ์นจํด ํ์์ ๋ํด ๋ฒ์ ๋์์ ํ ๊ถ๋ฆฌ๋ฅผ ๋ณด์ ํฉ๋๋ค.
ยฉ 2025 ์ฌ๋ฅ๋ท | All rights reserved.
๋๊ธ 0๊ฐ