Spring/Spring

[Spring] Transactional์˜ ์ดํ•ด

27200 2026. 3. 2. 11:38

๐Ÿ’ก ํŠธ๋žœ์žญ์…˜

๐Ÿค” ํŠธ๋žœ์žญ์…˜์ด๋ž€?

ํŠธ๋žœ์žญ์…˜์ด๋ž€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ˜น์€ ์œ ์‚ฌ ์‹œ์Šคํ…œ์—์„œ ํ•˜๋‚˜์˜ ์ƒํ˜ธ์ž‘์šฉ ๋‹จ์œ„์ด๋‹ค.
์ด๋Š” ๋ฐ์ดํ„ฐ์˜ ์ •ํ•ฉ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ๋ฐฉ๋ฒ•์ด๋‹ค.

 

์ด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์œ ์ง€ํ•˜๊ณ , ๋™์‹œ ์ ‘๊ทผํ•˜๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ๊ทธ๋žจ ๊ฐ„์˜ ๊ฒฉ๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•œ๋‹ค.

ํŠธ๋žœ์žญ์…˜ ๋‚ด SQL๋ฌธ๋“ค์€ ๋ชจ๋‘ ์„ฑ๊ณตํ•˜์—ฌ commit ๋˜๊ฑฐ๋‚˜, ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ ์ „์ฒด๊ฐ€ rollback ๋œ๋‹ค.

 

๐Ÿซจ ACID

ํŠธ๋žœ์žญ์…˜์ด ์–ด๋–ค ์†์„ฑ์„ ์ง€๋…€์•ผ ํ•˜๋Š”์ง€ ๋‚˜ํƒ€๋‚ด๋Š” ํ•ต์‹ฌ์ด๋‹ค.
4๊ฐ€์ง€ ๊ทœ์น™์„ ๋ชจ๋‘ ๋ณด์žฅํ•ด ์•ˆ์ „ํ•˜๊ฒŒ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค.

 

์›์ž์„ฑ(Atomicity)

  • All or Noting
  • ๋ชจ๋‘ ์„ฑ๊ณต or ๋ชจ๋‘ ์‹คํŒจ

ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์€ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋‚˜๋ˆ„์–ด์งˆ ์ˆ˜ ์—†๋Š” ๋‹จ์œ„์ด๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผํ•œ ๊ฒฝ๊ณผ๋ฅผ ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค.

์ฆ‰, ์ผ๋ถ€๋งŒ ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์‹คํŒจํ•˜๋Š” ์ƒํƒœ๋Š” ์กด์žฌํ•ด์„œ ์•ˆ ๋œ๋‹ค.

 

์ผ๊ด€์„ฑ(Consistency)

  • ํŠธ๋žœ์žญ์…˜ ์ด์ „๊ณผ ์ดํ›„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ํ•ญ์ƒ ์ผ๊ด€์ ์ธ ์ƒํƒœ์—ฌ์•ผ ํ•œ๋‹ค.
    • ํŠธ๋žœ์žญ์…˜์€ DB๋ฅผ Consistency -> Consistency๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

๋งŒ์•ฝ DB์˜ ์ •์˜๋œ ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•œ๋‹ค๋ฉด ํŠธ๋žœ์žญ์…˜์€ ๋กค๋ฐฑ๋˜์–ด์•ผ ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๊ณ„์ขŒ ์ž”๊ณ ๊ฐ€ -๊ฐ€ ๋  ์ˆ˜ ์—†๋„๋ก ์„ค์ •ํ•ด ๋‘์—ˆ๋‹ค๋ฉด ์ด๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์ง€์ผœ์•ผ ํ•œ๋‹ค.

 

๋…๋ฆฝ์„ฑ(Isolation)

  • ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ ์‹คํ–‰๋˜์–ด๋„, ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์€ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ด์–ด์•ผ ํ•œ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜ ๋ฐ–์— ์žˆ๋Š” ์–ด๋– ํ•œ ์—ฐ์‚ฐ๋„ ํŠธ๋žœ์žญ์…˜์˜ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์„ ๋ณผ ์ˆ˜ ์—†์–ด์•ผ ํ•œ๋‹ค.
  • DBMS๋Š” ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ isolation level์„ ์ œ๊ณตํ•œ๋‹ค.

 

์ง€์†์„ฑ(Durability)

  • ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋œ ํŠธ๋žœ์žญ์…˜์€ ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ˜์˜๋˜์–ด์•ผ ํ•œ๋‹ค.
  • ์ „์›์ด ๊บผ์ง„ ๋’ค์—๋„ ์ €์žฅ๋˜๋Š” ๋น„ํœ˜๋ฐœ์„ฑ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜์–ด์•ผ ํ•œ๋‹ค.

 

JDBC Template

catch (SQLException e) {
    try {
        connection.rollback();
    } catch (SQLException ex) {
        ex.addSuppressed(e);
        throw ex;
    }
    throw e;
}

 

๐Ÿ”Ž ๋‹จ๊ณ„๋ณ„ ์˜๋ฏธ

1๏ธโƒฃ dataSource.getConnection()
→ DB ์ปค๋„ฅ์…˜ ํš๋“

 

2๏ธโƒฃ setAutoCommit(false)
→ ์ž๋™ ์ปค๋ฐ‹ ๋„๊ธฐ (ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘)

 

3๏ธโƒฃ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰
→ ์—ฌ๋Ÿฌ SQL ์‹คํ–‰

 

4๏ธโƒฃ commit()
→ ์ •์ƒ ์ข…๋ฃŒ ์‹œ DB ๋ฐ˜์˜

 

5๏ธโƒฃ rollback()
→ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ๋˜๋Œ๋ฆฌ๊ธฐ

 

6๏ธโƒฃ close()
→ ์ปค๋„ฅ์…˜ ๋ฐ˜ํ™˜ (๋ณดํ†ต ํ’€๋กœ ๋ฐ˜ํ™˜๋จ)

 

์ฆ‰, ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ œ์–ดํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

 

ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๊ฐ€ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์— ๊ณ ์ •๋˜๊ฑฐ๋‚˜, AOP ๊ธฐ๋ฐ˜ ํŠธ๋žœ์žญ์…˜์ด ๋ถˆ๊ฐ€๋Šฅํ•˜์—ฌ ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค.

 

โ€ผ๏ธ Spring Transaction

์ •์˜

์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” ์ถ”์ƒํ™”๋œ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์œผ๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก
ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘/์ปค๋ฐ‹/๋กค๋ฐฑ์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

 

PlatformTransactionManager

 

Spring ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™”์˜ ์ค‘์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.

commit์™€ rollback ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

JDBC, JPA ๋“ฑ ๋ชจ๋‘ ์ด๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ Spring Transaction์„ ์ง€์›ํ•œ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ๊ธฐ์ˆ ์— ๋…๋ฆฝ์ ์ด๊ณ , ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„์„ค์ •์ด ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค.

org.springframework.transaction.PlatformTransactionManager ๊ฒฝ๋กœ์— ์กด์žฌํ•˜๋ฉฐ

ํ˜„์žฌ ํ™œ์„ฑํ™”๋œ ํŠธ๋žœ์žญ์…˜์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜, ์ง€์ •๋œ ์ „ํŒŒ(propagation) ๋™์ž‘์— ๋”ฐ๋ผ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๊ฒฉ๋ฆฌ ์ˆ˜์ค€(isolation level)์ด๋‚˜ ํƒ€์ž„์•„์›ƒ(timeout)๊ณผ ๊ฐ™์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์—๋งŒ ์ ์šฉ๋˜๋ฉฐ, ์ด๋ฏธ ํ™œ์„ฑํ™”๋œ ํŠธ๋žœ์žญ์…˜์— ์ฐธ์—ฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜ ์ •์˜ ์„ค์ •์ด ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €์—์„œ ์ง€์›๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ ์ ˆํ•œ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ๊ตฌํ˜„์ฒด๋Š” ์ง€์›๋˜์ง€ ์•Š๋Š” ์„ค์ •์ด ์‚ฌ์šฉ๋  ๊ฒฝ์šฐ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์œ„ ๊ทœ์น™์˜ ์˜ˆ์™ธ๋Š” read-only ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค. ๋ช…์‹œ์ ์ธ read-only ๋ชจ๋“œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ์ด ํ”Œ๋ž˜๊ทธ๋Š” ๋ฌด์‹œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ read-only ํ”Œ๋ž˜๊ทธ๋Š” ์ž ์žฌ์ ์ธ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ํžŒํŠธ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

์œ„์™€ ๊ฐ™์€ ์„ค๋ช…์„ ํ•˜๊ณ  ์žˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ DB์ ‘๊ทผ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ด€์‹ฌ์‚ฌ์˜ ์—…๋ฌด๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

 

โค๏ธ ์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜(@Transactional)

๊ฐœ๋…

Transaction ๊ด€๋ฆฌ๋ฅผ ๋ณ„๋„์˜ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ AOP๋กœ ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ณผ์ •์—์„œ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ธํ•œ ์ฝ”๋“œ ์ค‘๋ณต ๋ฌธ์ œ, ์†Œ์Šค์ฝ”๋“œ ์œ ์ง€ ๋ณด์ˆ˜ ์–ด๋ ค์›€์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์‚ฌ์šฉ

์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ณผ์ •์—์„œ @Transactional์„ ์ž…๋ ฅํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋งค๋ฒˆ ๋‘ ๊ฐœ์˜ import๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Œ์„ ๋А๊ผˆ์„ ๊ฒƒ์ด๋‹ค.

๋‘ ๊ฐœ๋Š” ๋ฌด์—‡์ด ๋‹ค๋ฅด๊ณ  ์–ด๋–ค ๊ฒƒ์„ ์„ ํƒํ•ด์•ผ ํ• ๊นŒ?

๐Ÿ“Š Spring Transaction vs Jakarta Transaction ๋น„๊ต

๊ตฌ๋ถ„ Spring Framework Transaction Jakarta Transcation
์–ด๋…ธํ…Œ์ด์…˜ ํŒจํ‚ค์ง€ org.springframework.transaction.annotation.Transactional jakarta.transaction.Transactional
์†Œ์† Spring Framework Jakarta EE (ํ‘œ์ค€)
๊ธฐ๋ฐ˜ ๊ธฐ์ˆ  Spring ์ž์ฒด ์ถ”์ƒํ™” + AOP JTA (Java Transaction API)
ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € PlatformTransactionManager JTA Transaction Manager
๊ธฐ๋ณธ ๋กค๋ฐฑ ์ •์ฑ… RuntimeException, Error ๋กค๋ฐฑ RuntimeException ๋กค๋ฐฑ (๊ตฌํ˜„์ฒด ์˜์กด)
Checked Exception ๋กค๋ฐฑ ๊ธฐ๋ณธ โŒ (์˜ต์…˜์œผ๋กœ ๊ฐ€๋Šฅ) ๊ธฐ๋ณธ โŒ (rollbackOn์œผ๋กœ ์ง€์ •)
rollback ์ปค์Šคํ„ฐ๋งˆ์ด์ง• rollbackFor, noRollbackFor rollbackOn, dontRollbackOn
์ „ํŒŒ ์˜ต์…˜(Propagation) REQUIRED, REQUIRES_NEW, NESTED ๋“ฑ ๋งค์šฐ ๋‹ค์–‘ REQUIRED, REQUIRES_NEW ๋“ฑ ์ผ๋ถ€๋งŒ
๊ฒฉ๋ฆฌ ์ˆ˜์ค€(Isolation) ์ง์ ‘ ์„ค์ • ๊ฐ€๋Šฅ ์ง์ ‘ ์„ค์ • ๋ถˆ๊ฐ€
timeout ์„ค์ • ๊ฐ€๋Šฅ ์ œํ•œ์ 
readOnly ์˜ต์…˜ ์žˆ์Œ (์ตœ์ ํ™” ํžŒํŠธ) ์—†์Œ
AOP ๊ธฐ๋ฐ˜ ๋™์ž‘ O (ํ”„๋ก์‹œ ๊ธฐ๋ฐ˜) ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ
ThreadLocal ์‚ฌ์šฉ ์‚ฌ์šฉ (๋™๊ธฐ ํŠธ๋žœ์žญ์…˜) ๊ตฌํ˜„์ฒด ์˜์กด
Reactive ์ง€์› O (ReactiveTransactionManager) X
์ฃผ ์‚ฌ์šฉ ํ™˜๊ฒฝ Spring Boot / Spring ๊ธฐ๋ฐ˜ ์•ฑ Jakarta EE ์„œ๋ฒ„ (WildFly ๋“ฑ)
์„ธ๋ฐ€ํ•œ ์ œ์–ด ๋งค์šฐ ๊ฐ•ํ•จ ๋น„๊ต์  ๋‹จ์ˆœ

Spring or Spring boot๋กœ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋Š” ํ™˜๊ฒฝ์ด๋ผ๋ฉด Spring Framework Transaction์„ ์„ ํƒํ•˜์—ฌ ์‚ฌ์šฉํ•˜์ž.

 

org.springframework.transaction.annotation.Transactional

ํด๋ž˜์Šค ์ฃผ์„ ๋ฒˆ์—ญ๋ฌธ

๋”๋ณด๊ธฐ

๊ฐœ๋ณ„ ๋ฉ”์„œ๋“œ ๋˜๋Š” ํด๋ž˜์Šค์— ํŠธ๋žœ์žญ์…˜ ์†์„ฑ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ด ์–ด๋…ธํ…Œ์ด์…˜์ด ํด๋ž˜์Šค ์ˆ˜์ค€์— ์„ ์–ธ๋˜๋ฉด, ํ•ด๋‹น ํด๋ž˜์Šค์™€ ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค์˜ ๋ชจ๋“  ๋ฉ”์„œ๋“œ์— ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‹จ, ํด๋ž˜์Šค ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ ์ƒ์œ„(์กฐ์ƒ) ํด๋ž˜์Šค์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒ์†๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•˜์œ„ ํด๋ž˜์Šค ์ˆ˜์ค€์˜ ์–ด๋…ธํ…Œ์ด์…˜์— ์ฐธ์—ฌํ•˜๋ ค๋ฉด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๋‹ค์‹œ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ๊ฐ€์‹œ์„ฑ ์ œ์•ฝ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ ˆํผ๋Ÿฐ์Šค ๋งค๋‰ด์–ผ์˜ Transaction Management ์„น์…˜์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

์ด ์–ด๋…ธํ…Œ์ด์…˜์€ ์ผ๋ฐ˜์ ์œผ๋กœ Spring์˜ org.springframework.transaction.interceptor.RuleBasedTransactionAttribute ํด๋ž˜์Šค์™€ ์ง์ ‘์ ์œผ๋กœ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ AnnotationTransactionAttributeSource๋Š” ์ด ์–ด๋…ธํ…Œ์ด์…˜์˜ ์†์„ฑ๋“ค์„ RuleBasedTransactionAttribute์˜ ์†์„ฑ์œผ๋กœ ์ง์ ‘ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Spring์˜ ํŠธ๋žœ์žญ์…˜ ์ง€์› ์ฝ”๋“œ๋Š” ์–ด๋…ธํ…Œ์ด์…˜ ์ž์ฒด๋ฅผ ์•Œ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.



์†์„ฑ ์˜๋ฏธ (Attribute Semantics)

์ด ์–ด๋…ธํ…Œ์ด์…˜์— ์‚ฌ์šฉ์ž ์ •์˜ ๋กค๋ฐฑ ๊ทœ์น™์ด ๊ตฌ์„ฑ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ํŠธ๋žœ์žญ์…˜์€ RuntimeException๊ณผ Error์— ๋Œ€ํ•ด์„œ๋Š” ๋กค๋ฐฑ๋˜์ง€๋งŒ, ์ฒดํฌ ์˜ˆ์™ธ(checked exception)์— ๋Œ€ํ•ด์„œ๋Š” ๋กค๋ฐฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋กค๋ฐฑ ๊ทœ์น™์€ ํŠน์ • ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ํŠธ๋žœ์žญ์…˜์„ ๋กค๋ฐฑํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋ฉฐ, ํƒ€์ž… ๋˜๋Š” ํŒจํ„ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์น™์€ rollbackFor / noRollbackFor ๋ฐ rollbackForClassName / noRollbackForClassName์„ ํ†ตํ•ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ๊ฐ ํƒ€์ž… ๊ธฐ๋ฐ˜ ๋˜๋Š” ํŒจํ„ด ๊ธฐ๋ฐ˜์œผ๋กœ ๊ทœ์น™์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์™ธ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กค๋ฐฑ ๊ทœ์น™์„ ์ •์˜ํ•œ ๊ฒฝ์šฐ(์˜ˆ: rollbackFor), ํ•ด๋‹น ํƒ€์ž…์€ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ์˜ ํƒ€์ž…๊ณผ ๋น„๊ตํ•˜์—ฌ ๋งค์นญ๋ฉ๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ, ์„ค์ •๋œ ์˜ˆ์™ธ ํƒ€์ž… C๊ฐ€ ์žˆ์„ ๋•Œ, ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ ํƒ€์ž… T๊ฐ€ C์™€ ๋™์ผํ•˜๊ฑฐ๋‚˜ C์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋ผ๋ฉด ๋งค์นญ๋œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ์ œ๊ณตํ•˜๋ฉฐ, ํŒจํ„ด ์‚ฌ์šฉ ์‹œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜๋„์น˜ ์•Š์€ ๋งค์นญ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด jakarta.servlet.ServletException.class๋ฅผ ์ง€์ •ํ•˜๋ฉด, jakarta.servlet.ServletException ๋ฐ ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค์— ๋Œ€ํ•ด์„œ๋งŒ ๋งค์นญ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ์™ธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กค๋ฐฑ ๊ทœ์น™์„ ์ •์˜ํ•œ ๊ฒฝ์šฐ, ํŒจํ„ด์€ ์˜ˆ์™ธ ํƒ€์ž…(๋ฐ˜๋“œ์‹œ Throwable์˜ ํ•˜์œ„ ํด๋ž˜์Šค์—ฌ์•ผ ํ•จ)์˜ ์ „์ฒด ํด๋ž˜์Šค ์ด๋ฆ„(FQCN)์ด๊ฑฐ๋‚˜ ๊ทธ ์ผ๋ถ€ ๋ฌธ์ž์—ด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ๋Š” ์™€์ผ๋“œ์นด๋“œ ์ง€์›์ด ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "jakarta.servlet.ServletException" ๋˜๋Š” "ServletException"์ด๋ผ๋Š” ๊ฐ’์€ jakarta.servlet.ServletException ๋ฐ ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค์™€ ๋งค์นญ๋ฉ๋‹ˆ๋‹ค.

์ฃผ์˜: ํŒจํ„ด์„ ์–ผ๋งˆ๋‚˜ ๊ตฌ์ฒด์ ์œผ๋กœ ์ง€์ •ํ• ์ง€, ๊ทธ๋ฆฌ๊ณ  ํŒจํ‚ค์ง€ ์ •๋ณด๋ฅผ ํฌํ•จํ• ์ง€(ํ•„์ˆ˜๋Š” ์•„๋‹˜)๋ฅผ ์‹ ์ค‘ํžˆ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "Exception"์€ ๊ฑฐ์˜ ๋ชจ๋“  ์˜ˆ์™ธ์™€ ๋งค์นญ๋˜๋ฏ€๋กœ ๋‹ค๋ฅธ ๊ทœ์น™์„ ๊ฐ€๋ฆด ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋ชจ๋“  ์ฒดํฌ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ๊ทœ์น™์„ ์ •์˜ํ•˜๋ ค๋Š” ๋ชฉ์ ์ด๋ผ๋ฉด "java.lang.Exception"์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค. "BaseBusinessException"์ฒ˜๋Ÿผ ๊ณ ์œ ํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์˜ˆ์™ธ๋ผ๋ฉด ์ „์ฒด ํด๋ž˜์Šค ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ํŒจํ„ด ๊ธฐ๋ฐ˜์œผ๋กœ ์ •์˜๋œ ๋กค๋ฐฑ ๊ทœ์น™์€ ์ด๋ฆ„์ด ์œ ์‚ฌํ•œ ์˜ˆ์™ธ๋‚˜ ์ค‘์ฒฉ ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์˜๋„์น˜ ์•Š์€ ๋งค์นญ์„ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ์˜ ์ด๋ฆ„์— ์„ค์ •๋œ ์˜ˆ์™ธ ํŒจํ„ด ๋ฌธ์ž์—ด์ด ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด ๋งค์นญ๋œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "com.example.CustomException"์ด๋ผ๋Š” ๊ทœ์น™์ด ์„ค์ •๋œ ๊ฒฝ์šฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ˆ์™ธ์—๋„ ๋งค์นญ๋ฉ๋‹ˆ๋‹ค:

com.example.CustomExceptionV2 (๊ฐ™์€ ํŒจํ‚ค์ง€์— ์žˆ์œผ๋‚˜ ์ด๋ฆ„์— ์ ‘๋ฏธ์‚ฌ๊ฐ€ ์ถ”๊ฐ€๋œ ๊ฒฝ์šฐ) com.example.CustomException$AnotherException (CustomException ๋‚ด๋ถ€์— ์„ ์–ธ๋œ ์ค‘์ฒฉ ํด๋ž˜์Šค)

์ด ์–ด๋…ธํ…Œ์ด์…˜์˜ ๋‹ค๋ฅธ ์†์„ฑ ์˜๋ฏธ์— ๋Œ€ํ•œ ๊ตฌ์ฒด์ ์ธ ์ •๋ณด๋Š” TransactionDefinition ๋ฐ org.springframework.transaction.interceptor.TransactionAttribute์˜ Javadoc์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.



ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ (Transaction Management)

์ด ์–ด๋…ธํ…Œ์ด์…˜์€ ์ผ๋ฐ˜์ ์œผ๋กœ org.springframework.transaction.PlatformTransactionManager์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” ์Šค๋ ˆ๋“œ ๋ฐ”์ธ๋”ฉ(thread-bound) ํŠธ๋žœ์žญ์…˜๊ณผ ํ•จ๊ป˜ ๋™์ž‘ํ•˜๋ฉฐ, ํ˜„์žฌ ์‹คํ–‰ ์Šค๋ ˆ๋“œ ๋‚ด์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ์ž‘์—…์— ํŠธ๋žœ์žญ์…˜์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋‹จ, ์ด ํŠธ๋žœ์žญ์…˜์€ ํ•ด๋‹น ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ์ƒˆ๋กญ๊ฒŒ ์‹œ์ž‘๋œ ์Šค๋ ˆ๋“œ๋กœ๋Š” ์ „ํŒŒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜๋Š” ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ org.springframework.transaction.ReactiveTransactionManager์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” ๋ฆฌ์•กํ‹ฐ๋ธŒ ํŠธ๋žœ์žญ์…˜์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ThreadLocal ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ Reactor Context๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ์ฐธ์—ฌ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ์ž‘์—…์€ ๋™์ผํ•œ ๋ฆฌ์•กํ‹ฐ๋ธŒ ํŒŒ์ดํ”„๋ผ์ธ ๋‚ด์—์„œ, ๋™์ผํ•œ Reactor Context ์•ˆ์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : ReactiveTransactionManager์™€ ํ•จ๊ป˜ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ, ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜์ด ์„ ์–ธ๋œ ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์•กํ‹ฐ๋ธŒ ํŒŒ์ดํ”„๋ผ์ธ์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. void ๋ฉ”์„œ๋“œ๋‚˜ ์ผ๋ฐ˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ผ๋ฐ˜์ ์ธ PlatformTransactionManager์™€ ์—ฐ๊ฒฐ๋˜์–ด์•ผ ํ•˜๋ฉฐ, ์˜ˆ๋ฅผ ๋“ค์–ด transactionManager()๋ฅผ ํ†ตํ•ด ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”์„œ๋“œ

public @interface Transactional {

    // ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ์ด๋ฆ„ ์ง€์ • (transactionManager์˜ ๋ณ„์นญ)
    // ์—ฌ๋Ÿฌ TransactionManager๊ฐ€ ์žˆ์„ ๋•Œ ํŠน์ • ๋งค๋‹ˆ์ €๋ฅผ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
    String value() default "";

    // ์‚ฌ์šฉํ•  PlatformTransactionManager Bean ์ด๋ฆ„ ์ง€์ •
    // ๋ฉ€ํ‹ฐ ๋ฐ์ดํ„ฐ์†Œ์Šค ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ
    String transactionManager() default "";

    // ํŠธ๋žœ์žญ์…˜์— ๋ผ๋ฒจ(ํƒœ๊ทธ)์„ ๋ถ€์—ฌ
    // ๋ชจ๋‹ˆํ„ฐ๋ง/์ถ”์ ์šฉ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์ด๋ฉฐ ํŠธ๋žœ์žญ์…˜ ๋™์ž‘์—๋Š” ์˜ํ–ฅ ์—†์Œ
    String[] label() default {};

    // ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ ์˜ต์…˜ ์„ค์ •
    // ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์ด ์žˆ์„ ๋•Œ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ์ง€ ๊ฒฐ์ • (๊ธฐ๋ณธ: REQUIRED)
    Propagation propagation() default Propagation.REQUIRED;

    // ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ์„ค์ •
    // ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์œ„ํ•œ ์„ค์ •์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ’์€ DB ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ
    Isolation isolation() default Isolation.DEFAULT;

    // ํŠธ๋žœ์žญ์…˜ ํƒ€์ž„์•„์›ƒ(์ดˆ ๋‹จ์œ„)
    // ์ง€์ • ์‹œ๊ฐ„ ์ดˆ๊ณผ ์‹œ ๋กค๋ฐฑ (๊ธฐ๋ณธ๊ฐ’์€ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ)
    int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

    // ํƒ€์ž„์•„์›ƒ์„ ๋ฌธ์ž์—ด๋กœ ์ง€์ •
    // SpEL ๋˜๋Š” ํ”„๋กœํผํ‹ฐ ๊ฐ’ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    String timeoutString() default "";

    // ์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜ ์—ฌ๋ถ€
    // ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ํžŒํŠธ (๊ฐ•์ œ ์ œํ•œ์€ ์•„๋‹˜)
    boolean readOnly() default false;

    // ์ง€์ •ํ•œ ์˜ˆ์™ธ ํƒ€์ž… ๋ฐœ์ƒ ์‹œ ๋กค๋ฐฑ
    // ํ•ด๋‹น ํƒ€์ž… ๋ฐ ํ•˜์œ„ ํด๋ž˜์Šค๊นŒ์ง€ ์ ์šฉ
    Class<? extends Throwable>[] rollbackFor() default {};

    // ์˜ˆ์™ธ ํด๋ž˜์Šค ์ด๋ฆ„(๋ฌธ์ž์—ด ํŒจํ„ด) ๊ธฐ๋ฐ˜ ๋กค๋ฐฑ ์ง€์ •
    // ์ด๋ฆ„์— ํ•ด๋‹น ๋ฌธ์ž์—ด์ด ํฌํ•จ๋˜๋ฉด ๋งค์นญ๋จ (์™€์ผ๋“œ์นด๋“œ ์—†์Œ)
    String[] rollbackForClassName() default {};

    // ์ง€์ •ํ•œ ์˜ˆ์™ธ ํƒ€์ž… ๋ฐœ์ƒ ์‹œ ๋กค๋ฐฑํ•˜์ง€ ์•Š์Œ
    // RuntimeException์ด๋ผ๋„ ์ปค๋ฐ‹ํ•˜๋„๋ก ์„ค์ • ๊ฐ€๋Šฅ
    Class<? extends Throwable>[] noRollbackFor() default {};

    // ์˜ˆ์™ธ ํด๋ž˜์Šค ์ด๋ฆ„(๋ฌธ์ž์—ด ํŒจํ„ด) ๊ธฐ๋ฐ˜ ๋กค๋ฐฑ ์ œ์™ธ ์ง€์ •
    String[] noRollbackForClassName() default {};
}

ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (Isolation Level)

๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ํŠธ๋žœ์žญ์…˜ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ํ—ˆ์šฉ ๋ฒ”์œ„๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์„ค์ •

ํŠธ๋žœ์žญ์…˜ ์ด์ƒ ํ˜„์ƒ

Dirty Read ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Œ
Non-repeatable Read ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‘ ๋ฒˆ ์กฐํšŒํ–ˆ๋Š”๋ฐ ๊ฐ’์ด ๋‹ฌ๋ผ์ง
Phantom Read ๊ฐ™์€ ์กฐ๊ฑด์œผ๋กœ ์กฐํšŒํ–ˆ๋Š”๋ฐ ํ–‰ ๊ฐœ์ˆ˜๊ฐ€ ๋‹ฌ๋ผ์ง

1. DEFAULT

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์„ค์ •๋œ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ๋”ฐ๋ฆ„
  • Spring์€ ๊ด€์—ฌํ•˜์ง€ ์•Š์Œ
  • ๋ณดํ†ต DB ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ

์ฐธ๊ณ :

  • MySQL(InnoDB) ๊ธฐ๋ณธ: REPEATABLE READ
  • Oracle ๊ธฐ๋ณธ: READ COMMITTED

2. READ_UNCOMMITTED

  • ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ ์กฐํšŒ ๊ฐ€๋Šฅ
  • Dirty Read ํ—ˆ์šฉ
  • ๊ฐ€์žฅ ๋‚ฎ์€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
  • ์ •ํ•ฉ์„ฑ ๋‚ฎ์Œ, ๋™์‹œ์„ฑ ๋†’์Œ
  • ๋Œ€๋ถ€๋ถ„์˜ ์ƒ์šฉ DB์—์„œ๋Š” ์‚ฌ์‹ค์ƒ READ_COMMITTED์ฒ˜๋Ÿผ ๋™์ž‘

3. READ_COMMITTED

  • ์ปค๋ฐ‹๋œ ๋ฐ์ดํ„ฐ๋งŒ ์กฐํšŒ ๊ฐ€๋Šฅ
  • Dirty Read ๋ฐฉ์ง€
  • Non-repeatable Read, Phantom Read๋Š” ๋ฐœ์ƒ ๊ฐ€๋Šฅ
  • ์‹ค๋ฌด์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ

4. REPEATABLE_READ

  • ๋™์ผ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์กฐํšŒ ์‹œ ํ•ญ์ƒ ๋™์ผ ๊ฐ’ ๋ณด์žฅ
  • Dirty Read, Non-repeatable Read ๋ฐฉ์ง€
  • Phantom Read๋Š” DB ๊ตฌํ˜„์— ๋”ฐ๋ผ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
  • MySQL ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€

5. SERIALIZABLE

  • ๊ฐ€์žฅ ๋†’์€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
  • ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜์„ ์ˆœ์ฐจ ์‹คํ–‰์ฒ˜๋Ÿผ ๋ณด์žฅ
  • Dirty / Non-repeatable / Phantom Read ๋ชจ๋‘ ๋ฐฉ์ง€
  • ๋™์‹œ์„ฑ ๋งค์šฐ ๋‚ฎ์Œ
  • ์„ฑ๋Šฅ ์ €ํ•˜ ๊ฐ€๋Šฅ์„ฑ ํผ
  • ๊ธˆ์œต/์ •์‚ฐ ๋“ฑ ๊ฐ•ํ•œ ์ •ํ•ฉ์„ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉ

Spring์—์„œ์˜ ํŠน์ง•

  • isolation ์˜ต์…˜์€ "์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜ ์ƒ์„ฑ ์‹œ์—๋งŒ" ์ ์šฉ
  • ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์— ์ฐธ์—ฌํ•˜๋Š” ๊ฒฝ์šฐ ๋ฌด์‹œ๋จ
  • DB๊ฐ€ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ ๊ฐ€๋Šฅ

ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ ์˜ต์…˜ (Propagation)

๊ธฐ์กด ํŠธ๋žœ์žญ์…˜ ์กด์žฌ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ํ˜„์žฌ ๋ฉ”์„œ๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ์ง€ ๊ฒฐ์ •

1. REQUIRED (๊ธฐ๋ณธ๊ฐ’)

  • ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ์ฐธ์—ฌ
  • ์—†์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ
  • ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์˜ต์…˜

2. SUPPORTS

  • ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ์ฐธ์—ฌ
  • ์—†์œผ๋ฉด ํŠธ๋žœ์žญ์…˜ ์—†์ด ์‹คํ–‰
  • ์กฐํšŒ์šฉ ๋ฉ”์„œ๋“œ์— ์ž์ฃผ ์‚ฌ์šฉ

3. REQUIRES_NEW

  • ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜ ์ƒ์„ฑ
  • ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์€ ์ž ์‹œ ์ค‘๋‹จ(Suspend)
  • ๋…๋ฆฝ์ ์ธ ์ปค๋ฐ‹/๋กค๋ฐฑ ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉ
  • ์˜ˆ: ๋กœ๊ทธ ์ €์žฅ, ๊ฐ์‚ฌ ๊ธฐ๋ก

4. MANDATORY

  • ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์ด ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผ ํ•จ
  • ์—†์œผ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ
  • ๋‹จ๋… ์‹คํ–‰์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ

5. NOT_SUPPORTED

  • ํŠธ๋žœ์žญ์…˜ ์—†์ด ์‹คํ–‰
  • ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜ ์žˆ์œผ๋ฉด ์ค‘๋‹จ
  • ๋ฝ์„ ํ”ผํ•˜๊ณ  ์‹ถ์€ ๋Œ€๋Ÿ‰ ์กฐํšŒ ๋“ฑ์— ์‚ฌ์šฉ

6. NEVER

  • ํŠธ๋žœ์žญ์…˜์ด ์กด์žฌํ•˜๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ
  • ์™„์ „ ๋น„ํŠธ๋žœ์žญ์…˜ ํ™˜๊ฒฝ ๊ฐ•์ œ

7. NESTED

  • ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์— ์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜ ์ƒ์„ฑ
  • Savepoint ๊ธฐ๋ฐ˜ ๋™์ž‘
  • ๋ถ€๋ชจ ๋กค๋ฐฑ ์‹œ ์ž์‹๋„ ๋กค๋ฐฑ
  • ์ž์‹ ๋กค๋ฐฑ์€ ๋ถ€๋ชจ์— ์˜ํ–ฅ ์—†์Œ
  • DataSourceTransactionManager์—์„œ๋งŒ ์ง€์›
  • JPA๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•˜์ง€ ์•Š์Œ

 

์ถœ์ฒ˜

https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html

https://velog.io/@betterfuture4/Spring-Transactional-%EC%B4%9D%EC%A0%95%EB%A6%AC

https://adjh54.tistory.com/378

https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html#transaction-declarative-annotations-method-visibility