Spring

[Spring] Spring @Transactional ์„ธ๋ถ€ ์„ค์ •

jeong_ii 2025. 1. 14. 00:14

๐Ÿ”น Spring Transaction์˜ ์„ธ๋ถ€ ์„ค์ •

Spring์—์„œ @Transactional ์„ธ๋ถ€ ์„ค์ •ํ•  ๋•Œ, ์ง€์›ํ•˜๋Š” ์ฃผ์š” ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์ „ํŒŒ ์†์„ฑ (Propagation)
  • ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (Isolation Level)
  • ์ฝ๊ธฐ ์ „์šฉ ์—ฌ๋ถ€ (Read-Only Flag)
  • ์ œํ•œ ์‹œ๊ฐ„ (Timeout)
  • ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ ์˜ˆ์™ธ ์„ค์ • (Rollback For, No Rollback For)

 

[ ์ „ํŒŒ ์†์„ฑ (Propagation) ]

Spring์ด ์ œ๊ณตํ•˜๋Š” ์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜(@Transactional)์˜ ์žฅ์  ์ค‘ ํ•˜๋‚˜๋Š” ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์˜ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด, ํฐ ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

ํŠธ๋žœ์žญ์…˜์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋ ค๋ฉด ์ „ํŒŒ ์†์„ฑ (Propagation)์„ ์„ค์ •ํ•ด์•ผ ํ•˜๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ• ์ง€, ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์— ์ฐธ์—ฌํ• ์ง€ ๋“ฑ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

 

[ ์ „ํŒŒ ์†์„ฑ ๋ชฉ๋ก ]

  • REQUIRED
  • SUPPORTS
  • MANDATORY
  • REQUIRES_NEW
  • NOT_SUPPORTED
  • NEVER
  • NESTED

โ—ฝ REQUIRED (๊ธฐ๋ณธ ์ „ํŒŒ ์†์„ฑ)

  • REQUIRED๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ , ์—†์œผ๋ฉด ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
  • ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ด๋ฉฐ ์ž์—ฐ์Šค๋Ÿฌ์šด ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ ๋ฐฉ์‹์ด๋ฉฐ, ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๊ฐ€ ์ง€์›ํ•œ๋‹ค.
  • ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋œ ํ›„, ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๊ฐ€ ์„ค์ •๋œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋™์ผํ•œ ํŠธ๋žœ์žญ์…˜์— ๋ฌถ์ธ๋‹ค.

โ—ฝ SUPPORTS

  • SUPPORTS๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ด๋ฏธ ์‹œ์ž‘๋œ ๊ฒฝ์šฐ ์ฐธ์—ฌํ•˜์ง€๋งŒ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํŠธ๋žœ์žญ์…˜ ์—†์ด ์‹คํ–‰๋œ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜์ด ์—†์–ด๋„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ(Connection)์ด๋‚˜ Hibernate์˜ ์„ธ์…˜(Session)์€ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ค‘์š”ํ•œ ์ž‘์—…์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์œผ๋ฉฐ, ํŠธ๋žœ์žญ์…˜์ด ํ•„์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์ ์ ˆํ•˜๋‹ค.

โ—ฝ MANDATORY

  • MANDATORY๋Š” ๋ฐ˜๋“œ์‹œ ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์ด ์กด์žฌํ•ด์•ผ ํ•˜๋ฉฐ, ์—†์œผ๋ฉด ์˜ˆ์™ธ(TransactionRequiredException)๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • ์ฆ‰, ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ๋ฐ˜๋“œ์‹œ ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ๋งŒ ์‹คํ–‰๋œ๋‹ค.
  • ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ํ•„์ˆ˜์ ์ธ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜๋ฉฐ, ๋…๋ฆฝ์ ์ธ ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์— ์ ํ•ฉํ•˜๋‹ค.

โ—ฝ REQUIRES_NEW

  • REQUIRES_NEW๋Š” ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•˜๋ฉฐ, ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ๋ณด๋ฅ˜(suspend)ํ•œ๋‹ค.
  • ์ฆ‰, ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜๊ณผ ๋ณ„๊ฐœ์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์‹คํ–‰๋˜๋ฉฐ, ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜๊ณผ ๋…๋ฆฝ์ ์ธ ์ปค๋ฐ‹/๋กค๋ฐฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • JTA(Java Transaction API) ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ํŠธ๋žœ์žญ์…˜ ๋ณด๋ฅ˜ ๊ธฐ๋Šฅ์ด ์ง€์›๋˜์–ด์•ผ ํ•œ๋‹ค.

โ—ฝ NOT_SUPPORTED

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

โ—ฝ NEVER

  • NEVER๋Š” ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ ํŠธ๋žœ์žญ์…˜์ด ์กด์žฌํ•˜๋ฉด ์˜ˆ์™ธ(IllegalTransactionStateException)๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜์ด ์ ˆ๋Œ€ ํฌํ•จ๋˜๋ฉด ํ•œ ๋˜๋Š” ์ž‘์—…(๋กœ๊น…, ๋ชจ๋‹ˆํ„ฐ๋ง, ๋‹จ์ˆœ ์กฐํšŒ ๋“ฑ)์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.

โ—ฝ NESTED

  • NESTED๋Š” ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ๊ทธ ๋‚ด๋ถ€์—์„œ ์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
  • ์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜์€ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์˜ ์ปค๋ฐ‹๊ณผ ๋กค๋ฐฑ์— ์˜ํ–ฅ์„ ๋ฐ›์ง€๋งŒ, ์ž์‹ ๋งŒ ๋กค๋ฐฑํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์„ ๊ฐ•์ œ๋กœ ์ปค๋ฐ‹ํ•˜๊ฑฐ๋‚˜ ๋กค๋ฐฑ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.
    • REQUIRES_NEW์™€์˜; ์ฐจ์ด์  
    • REQUIRES_NEW๋Š” ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•˜์—ฌ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜๊ณผ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.
    • ๋ฐ˜๋ฉด, NESTED๋Š” ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋ฉฐ, ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€๋งŒ, ์ž์‹ ๋งŒ ๋กค๋ฐฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์ค‘์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ๋กœ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ํ•จ๊ป˜ ์ €์žฅํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๊ฐ€์ •ํ•ด ๋ณด์ž.

  • ๋ฉ”์ธ ํŠธ๋žœ์žญ์…˜์—์„œ ์ค‘์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜์—์„œ ๋กœ๊ทธ๋ฅผ ์ €์žฅํ•œ๋‹ค.
  • ๋งŒ์•ฝ ๋กœ๊ทธ ์ €์žฅ์ด ์‹คํŒจํ•˜๋”๋ผ๋„, ๋ฉ”์ธ ์ž‘์—…์€ ๊ทธ๋Œ€๋กœ ์ง„ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค.
  • ํ•˜์ง€๋งŒ, ํ•ต์‹ฌ ์ž‘์—…์ด ์‹คํŒจํ•˜๋ฉด, ์ €์žฅ๋œ ๋กœ๊ทธ๋„ ํ•จ๊ป˜ ๋กค๋ฐฑ๋˜์–ด์•ผ ํ•œ๋‹ค
@Service
public class TransactionService {

    @Transactional(propagation = Propagation.NESTED)
    public void saveLog() {
        // ๋กœ๊ทธ ์ €์žฅ ๋กœ์ง (์ด ์ž‘์—…๋งŒ ๋กค๋ฐฑ๋  ์ˆ˜ ์žˆ์Œ)
    }

    @Transactional
    public void processImportantTask() {
        // ์ค‘์š”ํ•œ ์ž‘์—… ์ˆ˜ํ–‰
        saveLog();  // ์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰
    }
}

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ NESTED๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด,

  • ๋ฉ”์ธ ์ž‘์—…์ด ์‹คํŒจํ•˜๋ฉด, ์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜(๋กœ๊ทธ ์ €์žฅ)๋„ ๋กค๋ฐฑ๋œ๋‹ค.
  • ๋ฐ˜๋ฉด, ๋กœ๊ทธ ์ €์žฅ์ด ์‹คํŒจํ•ด๋„, ๋ฉ”์ธ ์ž‘์—…์€ ์ •์ƒ์ ์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค.

NESTED ์ „ํŒŒ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, JDBC 3.0์˜ ์ €์žฅ ํฌ์ธํŠธ(Savepoint)๋ฅผ ์ง€์›ํ•˜๋Š” ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

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

 

[ ์ ์šฉ ๊ฐ€๋Šฅ ํ™˜๊ฒฝ ]

  • DataSourceTransactionManager ์‚ฌ์šฉ (JDBC ๋“œ๋ผ์ด๋ฒ„๊ฐ€ Savepoint ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ด์•ผ ํ•จ)
  • JTA(Java Transaction API) ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ผ๋ถ€ WAS(Web Application Server)

 

์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜์—์„œ๋Š” @Transactional ์–ด๋…ธํ…Œ์ด์…˜์˜ propagation ์•จ๋ฆฌ๋จผํŠธ๋กœ ์›ํ•˜๋Š” ์ „ํŒŒ ์†์„ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ๊ฐ’์€ REQUIRED๋กœ ์„ค์ •๋˜์–ด ์žˆ๋‹ค.

๋˜ํ•œ, Spring์€ 7๊ฐ€์ง€ ์ „ํŒŒ ์†์„ฑ์„ ์ง€์›ํ•˜์ง€๋งŒ, ํ•ด๋‹น ์†์„ฑ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋‚˜ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ธฐ์ˆ ์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ „ํŒŒ ์†์„ฑ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉ ์ค‘์ธ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋‚˜ ๊ธฐ์ˆ ์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ์„ค์ •์ด ํ•„์š”ํ•œ์ง€ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

 

[ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (Isolation Level) ]

ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์€ ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ์— ์‹คํ–‰๋  ๋•Œ, ๊ฐ ํŠธ๋žœ์žญ์…˜์˜ ์ž‘์—… ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์— ์–ด๋–ป๊ฒŒ ๋…ธ์ถœ๋ ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์„ค์ •์ด๋‹ค. ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ๋†’์„์ˆ˜๋ก ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์ด ๋ณด์žฅ๋˜์ง€๋งŒ, ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค.

 

[ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ๋ชฉ๋ก ]

  • DEFAULT
  • READ_UNCOMMITTED
  • READ_COMMITTED
  • REPEATABLE_READ
  • SERIALIZABLE

โ—ฝ DEFAULT

  • DEFAULT๋Š” ์‚ฌ์šฉ ์ค‘์ธ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ธฐ์ˆ ์ด๋‚˜ DB ๋“œ๋ผ์ด๋ฒ„์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ๋”ฐ๋ฅธ๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ DB์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์€ READ_COMMITTED์ด์ง€๋งŒ, ์ผ๋ถ€ DB์—์„œ๋Š” ๊ธฐ๋ณธ ์„ค์ • ๊ฐ’์ด ๋‹ค๋ฅผ  ์ˆ˜ ์žˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ DEFAULT๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, DB ๋“œ๋ผ์ด๋ฒ„ ๋ฐ DBMS์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ๋ฐ˜๋“œ์‹œ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

โ—ฝ READ_UNCOMMITTED

  • READ_UNCOMMITTED๋Š” ๊ฐ€์žฅ ๋‚ฎ์€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์œผ๋กœ, ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋˜๊ธฐ ์ „์— ๋ฐœ์ƒํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋„ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ์กฐํšŒ๋  ์ˆ˜ ์žˆ๋‹ค.
  • ์ฆ‰, Dirty Read(๋”ํ‹ฐ ๋ฆฌ๋“œ) ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์ด ๋ณด์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ํ•˜์ง€๋งŒ, ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ๋‚ฎ์„์ˆ˜๋ก ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜๋ฏ€๋กœ, ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ๋ณด๋‹ค ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•œ ๊ฒฝ์šฐ์— ์˜๋„์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ๋„ ํ•œ๋‹ค.

โ—ฝ READ_COMMITTED

  • READ_COMMITTED๋Š” ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์œผ๋กœ, ์ปค๋ฐ‹์ด ์™„๋ฃŒ๋œ ๋ฐ์ดํ„ฐ๋งŒ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅํ•œ๋‹ค.
  • ์ฆ‰, ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์•„์ง ์ปค๋ฐ‹ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์—†๋‹ค.
  • ํ•˜์ง€๋งŒ ํŠธ๋žœ์žญ์…˜์ด ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‘ ๋ฒˆ ์กฐํšŒํ•  ๋•Œ, ๊ทธ ์‚ฌ์ด์— ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ’์„ ์ฝ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ˜„์ƒ์„ Non-Repeatable Read(๋น„๋ฐ˜๋ณต ์ฝ๊ธฐ) ๋ฌธ์ œ๋ผ๊ณ  ํ•œ๋‹ค.
  • Spring์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์€ DEFAULT์ด์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ DBMS๋Š” READ_COMMITTED๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€์žฅ ๋„๋ฆฌ ์“ฐ์ธ๋‹ค.

โ—ฝ REPEATABLE_READ

  • REPEATABLE_READ๋Š” ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ์กฐํšŒํ•œ ๋ฐ์ดํ„ฐ(row)๋ฅผ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋„๋ก ๋ณด์žฅํ•œ๋‹ค.
  • ์ฆ‰, ํŠธ๋žœ์žญ์…˜์ด ์ง„ํ–‰๋˜๋Š” ๋™์•ˆ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋ฉด ํ•ญ์ƒ ๋™์ผํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜๋ฐ›๋Š”๋‹ค.
  • ํ•˜์ง€๋งŒ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ(row)๋ฅผ ์ถ”๊ฐ€(INSERT)ํ•˜๋Š” ๊ฒƒ์€ ํ—ˆ์šฉ๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ, SELECT๋ฌธ์„ ํ†ตํ•ด ํŠน์ • ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ–ˆ์„ ๋•Œ, ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๊ธฐ ์ „์— ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ์ด๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ˜„์ƒ์„ Phantom Read(ํŒฌํ…€ ๋ฆฌ๋“œ) ๋ฌธ์ œ๋ผ๊ณ  ํ•œ๋‹ค.

โ—ฝ SERIALIZABLE

  • SERIALIZABLE๋Š” ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์œผ๋กœ, ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋„๋ก ๊ฐ•์ œํ•œ๋‹ค.
  • ์ฆ‰, ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์€ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค.
  • ์ด ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์—์„œ๋Š” ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ง๋ ฌํ™”๋˜์–ด ์‹คํ–‰๋˜๋ฏ€๋กœ, Dirty Read, Non-Repeatable Read, Phantom Read ๋ฌธ์ œ๊ฐ€ ๋ชจ๋‘ ๋ฐฉ์ง€๋œ๋‹ค.
  • ํ•˜์ง€๋งŒ, ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ์ €ํ•˜๋  ์ˆ˜ ์žˆ์–ด, ๊ทน๋„๋กœ ๋†’์€ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜์—์„œ๋Š” @Transactional ์–ด๋…ธํ…Œ์ด์…˜์˜ isolation ์•จ๋ฆฌ๋จผํŠธ๋กœ ์›ํ•˜๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ ๊ฐ’์€ DEFAULT๋กœ ์„ค์ •๋˜์–ด ์žˆ๋‹ค.

@Transactional(isolation = Isolation.DEFAULT)  
@Transactional(isolation = Isolation.READ_COMMITTED)

 

[ ์ฝ๊ธฐ ์ „์šฉ ์—ฌ๋ถ€ (Read-Only Flag) ]

@Transactional(readOnly=true)

Spring์—์„œ๋Š” ํŠธ๋žœ์žญ์…˜์„ ๋‹ค์Œ  ๋‘ ๊ฐ€์ง€ ๋ชฉ์ ์œผ๋กœ ์ฝ๊ธฐ ์ „์šฉ(Read-Only)์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์„ฑ๋Šฅ ์ตœ์ ํ™” : ๋ถˆํ•„์š”ํ•œ ํŠธ๋žœ์žญ์…˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ตœ์†Œํ™”ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค.
  • ์“ฐ๊ธฐ ๋ฐฉ์ง€ : ์˜๋„ํ•˜์ง€ ์•Š์€ INSERT, UPDATE, DELETE ์ž‘์—…์„ ๋ฐฉ์ง€ํ•œ๋‹ค.

ํŠธ๋žœ์žญ์…˜์„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•˜๋ฉด, ํ•ด๋‹น ์ •๋ณด๊ฐ€ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €์—๊ฒŒ ์ „๋‹ฌ๋˜๋ฉฐ, ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋Š” ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ตœ์ ํ™”๋œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๋‹ค๋งŒ, ์ผ๋ถ€ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋Š” ์ฝ๊ธฐ ์ „์šฉ ์„ค์ •์„ ๋ฌด์‹œํ•˜๊ณ  ์“ฐ๊ธฐ ์ž‘์—…์„ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ, ์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ INSERT, UPDATE, DELETE ์ž‘์—…์ด ์ˆ˜ํ–‰๋˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

[ ์ œํ•œ ์‹œ๊ฐ„ (Timeout) ]

@Transactional(timeout=10)

timeout ์†์„ฑ์„ ์ด์šฉํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์— ์ œํ•œ ์‹œ๊ฐ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ’์€ ์ดˆ ๋‹จ์œ„์˜ ์ •์ˆ˜(int)๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ๋ฌธ์ž์—ด๋กœ ์ง€์ •ํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋ฉด timeoutString์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

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

 

[ ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ ์˜ˆ์™ธ ์„ค์ • (Rollback For, No Rollback For) ]

// MyException ๋ฐœ์ƒ ์‹œ ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ
@Transactional(rollbackFor=MyException.class)
// MyException ๋ฐœ์ƒ ์‹œ ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ X
@Transactional(noRollbackFor=MyException.class)

์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋กค๋ฐฑํ•˜๊ณ , ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ฒดํฌ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ปค๋ฐ‹ํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ์ฒดํฌ ์˜ˆ์™ธ๋ฅผ ์ปค๋ฐ‹ ๋Œ€์ƒ์œผ๋กœ ์‚ผ์€ ์ด์œ ๋Š”, ์ฒดํฌ ์˜ˆ์™ธ๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์˜ˆ์™ธ์ ์ธ ์ƒํ™ฉ๋ณด๋‹ค๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—์„œ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

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

ํ•˜์ง€๋งŒ ํŠธ๋žœ์žญ์…˜์˜ ๋กค๋ฐฑ/์ปค๋ฐ‹ ๋™์ž‘ ๋ฐฉ์‹์˜ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์„ค์ •์„ ํ†ตํ•ด ๋™์ž‘ ๋ฐฉ์‹์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์ปค๋ฐ‹ ๋Œ€์ƒ์œผ๋กœ ์‚ผ๊ณ  ์‹ถ์€ ์ฒดํฌ ์˜ˆ์™ธ๋‚˜ ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•˜๋ ค๋ฉด rollbackFor ๋˜๋Š” rollbackForClassName์„ ์‚ฌ์šฉํ•˜๊ณ , ๋กค๋ฐฑ ๋Œ€์ƒ์ธ ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ๋ฅผ ์ปค๋ฐ‹ ๋Œ€์ƒ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด noRollbackFor ๋˜๋Š” noRollbackForClassName์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

์œ„์—์„œ ์„ค๋ช…ํ•œ ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜ ์†์„ฑ๋“ค์€ ๊ฐ ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„ ์„ค์ •์—์„œ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, readOnly ์†์„ฑ๋งŒ ํ™œ์šฉํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. ์„ธ๋ฐ€ํ•œ ์†์„ฑ์€ DBMS๋‚˜ WAS์˜ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ์„ค์ •์„ ํ†ตํ•ด ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 

 

 

 

๐Ÿ“ƒ reference