# νŠΈλžœμž­μ…˜ μ „νŒŒμ— κ΄€ν•˜μ—¬
Study Repository

νŠΈλžœμž­μ…˜ μ „νŒŒμ— κ΄€ν•˜μ—¬

by rlaehddnd0422

νŠΈλžœμž­μ…˜ μ „νŒŒλž€?

'ν•œ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ„ ν˜ΈμΆœν•  λ•Œ μ–΄λ–»κ²Œ μ²˜λ¦¬ν•˜λŠ” κ°€?'에 λŒ€ν•œ κ°œλ…μž…λ‹ˆλ‹€.


각각의 νŠΈλžœμž­μ…˜μ΄ λ³„κ°œλ‘œ μˆ˜ν–‰λ˜λŠ” 경우

 μš°μ„  두 νŠΈλžœμž­μ…˜μ΄ 각각 λ”°λ‘œ μ‚¬μš©λ˜λŠ” 경우λ₯Ό ν™•μΈν•΄λ΄…μ‹œλ‹€.

@Test
void double_commit()
{
    log.info("νŠΈλžœμž­μ…˜1 μ‹œμž‘");
    TransactionStatus status1 = transactionManager.getTransaction(new DefaultTransactionAttribute());
    log.info("νŠΈλžœμž­μ…˜1 컀밋 μ‹œμž‘");
    transactionManager.commit(status1);

    log.info("νŠΈλžœμž­μ…˜2 μ‹œμž‘");
    TransactionStatus status2 = transactionManager.getTransaction(new DefaultTransactionAttribute());
    log.info("νŠΈλžœμž­μ…˜2 컀밋 μ‹œμž‘");
    transactionManager.commit(status2);
}
νŠΈλžœμž­μ…˜μ„ μ‹œμž‘ν• λ•ŒλŠ” @Transactional을 μ‚¬μš©ν•˜λŠ”κ²Œ 톡상적이긴 ν•©λ‹ˆλ‹€λ§Œ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €μ—μ„œ 컀λ„₯μ…˜μ„ μ–»μ–΄ νŠΈλžœμž­μ…˜μ˜ λ™μž‘κ³Όμ •μ„ μ„€λͺ…ν•˜κΈ° μœ„ν•΄ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό 직접 μ‚¬μš©ν•΄ νŠΈλžœμž­μ…˜μ„ μˆ˜ν–‰ν–ˆμŠ΅λ‹ˆλ‹€.

νŠΈλžœμž­μ…˜1이 μ‹œμž‘λ˜κ³  μ»€λ°‹λœ 이후 νŠΈλžœμž­μ…˜2κ°€ ν˜ΈμΆœλ˜μ—ˆκΈ° λ•Œλ¬Έμ—, λ™μž‘κ³Όμ •μ€ μ΄λ ‡μŠ΅λ‹ˆλ‹€.

  1. getTransaction()으둜 νŠΈλžœμž­μ…˜ μ‹œμž‘ 
    1. νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €κ°€ DataSourceλ₯Ό 기반으둜 컀λ„₯μ…˜μ„ μƒμ„±ν•΄μ„œ νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €μ— 보관
  2. 둜직 μˆ˜ν–‰ by 1-1μ—μ„œ λ³΄κ΄€λœ 컀λ„₯μ…˜μ„ 기반으둜 SQL μˆ˜ν–‰ (μƒλž΅)
  3. commit() / rollback()  

μ΄λ ‡κ²Œ 각각 μˆ˜ν–‰λ˜λŠ” 경우 컀λ„₯μ…˜μ΄ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— νŠΈλžœμž­μ…˜1κ³Ό νŠΈλžœμž­μ…˜2λŠ” λ³„κ°œμ˜ νŠΈλžœμž­μ…˜μœΌλ‘œ μˆ˜ν–‰λ©λ‹ˆλ‹€.

즉, νŠΈλžœμž­μ…˜1κ³Ό νŠΈλžœμž­μ…˜2λŠ” μ„œλ‘œ μƒν˜Έ λ…λ¦½μ μœΌλ‘œ μ‹œν–‰λ˜κΈ° λ•Œλ¬Έμ— 각각의 컀밋/둀백의 κ²°κ³Όκ°€ μ„œλ‘œμ—κ²Œ 영ν–₯을 μ£Όμ§€μ•ŠμŠ΅λ‹ˆλ‹€.

 

κ·Έλ ‡λ‹€λ©΄ νŠΈλžœμž­μ…˜1μ—μ„œ νŠΈλžœμž­μ…˜2λ₯Ό ν˜ΈμΆœν•˜λŠ” κ²½μš°λŠ” μ–΄λ–¨κΉŒμš”?


νŠΈλžœμž­μ…˜ 진행쀑에 μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μ„ ν˜ΈμΆœν•˜λŠ” 경우  : νŠΈλžœμž­μ…˜ μ „νŒŒ

ν•˜λ‚˜μ˜ νŠΈλžœμž­μ…˜ 진행쀑에 μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μ„ ν˜ΈμΆœν•˜λŠ” 것을 νŠΈλžœμž­μ…˜ μ „νŒŒλΌκ³ ν•©λ‹ˆλ‹€.

 

ν•˜λ‚˜μ˜ νŠΈλžœμž­μ…˜ 진행쀑에 μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μ„ ν˜ΈμΆœν•˜κ²Œ 되면 μ–΄λ–»κ²Œ λ™μž‘ν• κΉŒμš”? 

 

1. 두 νŠΈλžœμž°μ…•μ€ ν•˜λ‚˜μ˜ 물리 νŠΈλžœμž­μ…˜μœΌλ‘œ 묢이게 λ©λ‹ˆλ‹€.

2. ν•˜λ‚˜μ˜ 물리 νŠΈλžœμž­μ…˜ λ‚΄μ˜ 각각의 νŠΈλžœμž­μ…˜μ€ 논리 νŠΈλžœμž­μ…˜μœΌλ‘œ κ΅¬λΆ„ν•©λ‹ˆλ‹€.

 

 

이 λ•Œ μ€‘μš”ν•œ 원칙이 μžˆμŠ΅λ‹ˆλ‹€.

1. λͺ¨λ“  논리 νŠΈλžœμž­μ…˜μ΄ μ»€λ°‹λ˜μ–΄μ•Ό 물리 νŠΈλžœμž­μ…˜μ΄ μ»€λ°‹λ©λ‹ˆλ‹€.

2. ν•˜λ‚˜μ˜ λ…Όλ¦¬νŠΈλžœμž­μ…˜μ΄λΌλ„ λ‘€λ°±λ˜λŠ” 경우 물리 νŠΈλžœμž­μ…˜μ€ λ‘€λ°±λ©λ‹ˆλ‹€.

 

νŠΈλžœμž­μ…˜2λŠ” νŠΈλžœμž­μ…˜1에 μ˜ν•΄μ„œ 호좜된 νŠΈλžœμž­μ…˜ μ΄λ―€λ‘œ μ‹ κ·œ νŠΈλžœμž­μ…˜μœΌλ‘œ μ‹œμž‘λ˜μ§€ μ•Šκ³ , κΈ°μ‘΄ νŠΈλžœμž­μ…˜μΈ νŠΈλžœμž­μ…˜1에 participate ν•˜μ—¬ λ™μž‘ν•©λ‹ˆλ‹€. 

 

Q. μ‹ κ·œ νŠΈλžœμž­μ…˜μΈμ§€ μ°Έμ—¬ νŠΈλžœμž­μ…˜μΈμ§€ λ‚΄λΆ€μ—μ„œ μ–΄λ–»κ²Œ νŒŒμ•…ν• κΉŒ?
A. λ‚΄λΆ€μ μœΌλ‘œ νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €λ₯Ό 톡해 κΈ°μ‘΄ νŠΈλžœμž­μ…˜μ΄ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•˜κ³ , κΈ°μ‘΄ νŠΈλžœμž­μ…˜μ΄ 있으면 같은 컀λ„₯μ…˜μ„ μ‚¬μš©ν•˜λ„λ‘ μ„€μ •λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.


νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λŠ” νŠΈλžœμž­μ…˜μ„ μƒμ„±ν•œ κ²°κ³Όλ₯Ό TransactionStatus에 λ‹΄μ•„μ„œ λ¦¬ν„΄ν•˜λŠ”λ°, μ—¬κΈ°μ„œ isNewTransaction을 톡해 μ‹ κ·œ νŠΈλžœμž­μ…˜ μ—¬λΆ€λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

μ°Έμ—¬ νŠΈλžœμž­μ…˜μ€ μ–΄λ–€ 의미λ₯Ό κ°€μ§ˆκΉŒμš”?

μ°Έμ—¬ νŠΈλžœμž­μ…˜μ€ 말 κ·ΈλŒ€λ‘œ κΈ°μ‘΄ νŠΈλžœμž­μ…˜μ— "μ°Έμ—¬"ν•˜λŠ” νŠΈλžœμž­μ…˜ μž…λ‹ˆλ‹€. λ”°λΌμ„œ μ°Έμ—¬ νŠΈλžœμž­μ…˜μ΄ μ»€λ°‹λ˜μ–΄λ„, μ‹ κ·œ νŠΈλžœμž­μ…˜μ΄ μ»€λ°‹λ˜μ§€ μ•ŠμœΌλ©΄ 둀백되기 λ•Œλ¬Έμ— μ°Έμ—¬ νŠΈλžœμž­μ…˜μ„ μ»€λ°‹ν•˜λŠ” μž‘μ—…μ€ μ‹€μ œλ‘œ 논리적 νŠΈλžœμž­μ…˜μ΄λ‚˜ 물리적 νŠΈλžœμž­μ…˜μ„ μ»€λ°‹ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 쑰금 더 μ‰½κ²Œ λ§ν•˜λ©΄, μ°Έμ—¬ νŠΈλžœμž­μ…˜μ— commit()을 걸어주어도 μ‹€μ œλ‘œλŠ” μ•„λ¬΄λŸ° λ™μž‘μ„ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Q. μ°Έμ—¬ νŠΈλžœμž­μ…˜μ΄ rollback()을 μˆ˜ν–‰ν•΄λ„ μ•„λ¬΄λŸ° λ™μž‘μ„ ν•˜μ§€ μ•Šλ‚˜μš”?
A. 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€. λ’€μ—μ„œ μ°Έμ—¬(λ‚΄λΆ€) νŠΈλžœμž­μ…˜μ˜ λ‘€λ°± μ‹œ λ™μž‘κ³Όμ •μ„ μ‚΄νŽ΄λ³΄κ² μ§€λ§Œ, μ°Έμ—¬ νŠΈλžœμž­μ…˜μ—μ„œ rollback을 μˆ˜ν–‰ν•˜λ©΄ μ‹ κ·œ νŠΈλžœμž­μ…˜μ—κ²Œ rollbackOnly μ˜΅μ…˜μ„ 전달해 쀌으둜써 물리 νŠΈλžœμž­μ…˜μ΄ rollback λ˜κ²Œλ” λ™μž‘ν•˜λ„λ‘ μœ λ„ν•©λ‹ˆλ‹€.

νŠΈλžœμž­μ…˜ μ „νŒŒ - μ™ΈλΆ€ λ‘€λ°± 

μš”μ²­ flow

 

1. νŠΈλžœμž­μ…˜ 1 호좜

- νŠΈλžœμž­μ…˜ 1μ—μ„œλŠ” νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό getTransaction()으둜 ν˜ΈμΆœν•˜μ—¬ νŠΈλžœμž­μ…˜μ„ μ‹œμž‘ν•©λ‹ˆλ‹€.

- νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λŠ” κΈ°μ‘΄ νŠΈλžœμž­μ…˜μ΄ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€. 

- μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ DataSourceλ₯Ό 톡해 컀λ„₯μ…˜μ„ 생성해 동기화 λ§€λ‹ˆμ €μ— λ³΄κ΄€ν•©λ‹ˆλ‹€.

- 컀λ„₯μ…˜μ„ 기반으둜 λ‘œμ§μ—μ„œ SQL μˆ˜ν–‰

 

2. νŠΈλžœμž­μ…˜ 1μ—μ„œ νŠΈλžœμž­μ…˜ 2 호좜 

- νŠΈλžœμž­μ…˜ 2 λ˜ν•œ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό getTransaction()으둜 ν˜ΈμΆœν•˜μ—¬ νŠΈλžœμž­μ…˜μ„ μ‹œμž‘ν•©λ‹ˆλ‹€.

- νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λŠ” κΈ°μ‘΄ νŠΈλžœμž­μ…˜μ΄ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€.

- κΈ°μ‘΄ νŠΈλžœμž­μ…˜μ΄ μ‘΄μž¬ν•˜λ―€λ‘œ 컀λ„₯μ…˜μ„ μ‚¬μš©ν•˜μ—¬ λ‘œμ§μ—μ„œ SQL을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.

 

 

응닡 flow

1. νŠΈλžœμž­μ…˜ 2 컀밋 (μ‹€μ œ μ»€λ°‹λ™μž‘ μˆ˜ν–‰ X)

- μ‹ κ·œ νŠΈλžœμž­μ…˜μ΄ μ•„λ‹Œ μ°Έμ—¬ νŠΈλžœμž­μ…˜ 이기 λ•Œλ¬Έμ— 컀밋을 ν˜ΈμΆœν•΄λ„ μˆ˜ν–‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

2. νŠΈλžœμž­μ…˜ 1 λ‘€λ°± 

- μ‹ κ·œ νŠΈλžœμž­μ…˜μ΄κΈ° λ•Œλ¬Έμ— 물리 νŠΈλžœμž­μ…˜μ„ rollback()ν•©λ‹ˆλ‹€.

 

Test Code

@Test
void outer_rollback()
{
    log.info("μ™ΈλΆ€ νŠΈλžœμž­μ…˜ μ‹œμž‘");
    TransactionStatus outer = transactionManager.getTransaction(new DefaultTransactionAttribute());
    log.info("outer.isNewTransaction() = {}", outer.isNewTransaction());

    innerCommit();

    log.info("μ™ΈλΆ€ νŠΈλžœμž­μ…˜ λ‘€λ°±");
    transactionManager.rollback(outer);
}
private void innerCommit() {
    log.info("λ‚΄λΆ€ νŠΈλžœμž­μ…˜ μ‹œμž‘");
    TransactionStatus inner = transactionManager.getTransaction(new DefaultTransactionAttribute());
    log.info("λ‚΄λΆ€ νŠΈλžœμž­μ…˜ 컀밋");
    transactionManager.commit(inner);
}

log

  • innerCommit()μ—μ„œ commit()을 ν˜ΈμΆœν•΄λ„ μ‹€μ œ 컀밋이 이루어지지 μ•ŠλŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ΄ μ‹œμž‘λ˜κ³  νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό 톡해 μ‹ κ·œ νŠΈλžœμž­μ…˜μΈμ§€ ν™•μΈν•˜κ³ , μ‹ κ·œ νŠΈλžœμž­μ…˜μ΄ μ•„λ‹ˆλ―€λ‘œ κΈ°μ‘΄ νŠΈλžœμž­μ…˜μ— Participatingν•˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ΄ λ‘€λ°±λ˜μ–΄ 전체 물리 νŠΈλžœμž­μ…˜μ΄ λ‘€λ°±λ˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

νŠΈλžœμž­μ…˜ μ „νŒŒ - λ‚΄λΆ€ λ‘€λ°±

κ·Έλ ‡λ‹€λ©΄ μ‹€μ œ νŠΈλžœμž­μ…˜μ΄ μ•„λ‹Œ μ°Έμ—¬ νŠΈλžœμž­μ…˜μ—μ„œ 둀백이 μΌμ–΄λ‚˜λ©΄ μ–΄λ–»κ²Œ λ κΉŒμš”?

μš”μ²­ 흐름은 λ™μΌν•˜κΈ° λ•Œλ¬Έμ— μƒλž΅ν•˜κ³ , μ‘λ‹΅νλ¦„λ§Œ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

응닡 Flow

1. νŠΈλžœμž­μ…˜ 2(λ‚΄λΆ€ νŠΈλžœμž­μ…˜) μ—μ„œ rollback 호좜

- λ§ˆμ°¬κ°€μ§€λ‘œ μ‹ κ·œ νŠΈλžœμž­μ…˜μ΄ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— μ‹€μ œ rollback을 ν˜ΈμΆœν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

- λŒ€μ‹  νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €μ— rollbackOnlyμ˜΅μ…˜μ„ true둜 μ„€μ •ν•©λ‹ˆλ‹€.

 

2. νŠΈλžœμž­μ…˜ 1(μ™ΈλΆ€ νŠΈλžœμž­μ…˜)μ—μ„œ commit 호좜

- μ‹ κ·œ νŠΈλžœμž­μ…˜μ΄ λ§žμ§€λ§Œ νŠΈλžœμž­μ…˜λ§€λ‹ˆμ €μ— rollbackOnly μ˜΅μ…˜μ΄ true둜 μ„€μ •λ˜μ–΄ μžˆμ–΄ commitν•˜μ§€ μ•Šκ³  물리 νŠΈλžœμž­μ…˜μ„ λ‘€λ°±ν•©λ‹ˆλ‹€

- 이 λ•Œ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λŠ” μ™ΈλΆ€ νŠΈλžœμž­μ…˜ μ½”λ“œμ— UnexpectedRollbackException μ˜ˆμ™Έλ₯Ό λ˜μ§‘λ‹ˆλ‹€.

 

 

TestCode

@Test
void inner_rollback()
{
    log.info("μ™ΈλΆ€ νŠΈλžœμž­μ…˜ μ‹œμž‘");
    TransactionStatus outer = transactionManager.getTransaction(new DefaultTransactionAttribute());
    log.info("outer.isNewTransaction() = {}", outer.isNewTransaction());

    innerRollback();

    log.info("μ™ΈλΆ€ νŠΈλžœμž­μ…˜ 컀밋");
    assertThatThrownBy(() -> transactionManager.commit(outer))
            .isInstanceOf(UnexpectedRollbackException.class);
}

λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ΄ 둀백을 호좜 β–ΆοΈŽ marking existing transaction as rollback-only(κΈ°μ‘΄ νŠΈλžœμž­μ…˜μ— rollbackOnly λ§ˆν‚Ή)

 

λ‘€λ°± μ „μš© ν‘œμ‹œ(rollbackOnly)κ°€ 있으면 μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ„ commit해도 물리 νŠΈλžœμž­μ…˜μ„ μ»€λ°‹ν•˜λŠ” 것이 μ•„λ‹ˆλΌ λ‘€λ°±ν•©λ‹ˆλ‹€.

μ™ΈλΆ€ νŠΈλžœμž­μ…˜κ³Ό λ‚΄λΆ€ νŠΈλžœμž­μ…˜ λΆ„λ¦¬ν•˜κΈ° - REQUIRES_NEW μ˜΅μ…˜ 

Q. μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ΄ λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ„ ν˜ΈμΆœν•  λ•Œ, μ‹ κ·œ νŠΈλžœμž­μ…˜μ„ μ‹œμž‘ν•˜κ²Œ ν•˜λŠ” 방법은 μ—†μ„κΉŒμš”?
A. λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ— propagation μ˜΅μ…˜μ„ REQUIRED_NEW으둜 μ„€μ •ν•΄μ£Όλ©΄ μ‹ κ·œ νŠΈλžœμž­μ…˜μœΌλ‘œ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 방법은 λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ— λ¬Έμ œκ°€ 생겨도 μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ— 영ν–₯을 주지 μ•ŠμŠ΅λ‹ˆλ‹€.

λ°˜λŒ€λ‘œ μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ— λ¬Έμ œκ°€ 생겨도 λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ— 영ν–₯을 주지 μ•ŠμŠ΅λ‹ˆλ‹€.

 

REQUIRES_NEW μ˜΅μ…˜μ„ μ‚¬μš©ν•˜λ©΄ κΈ°μ‘΄ 컀λ„₯μ…˜μ„ μ‚¬μš©ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μ„ μ‹œμž‘ν•˜κΈ° λ•Œλ¬Έμ— μ™ΈλΆ€ νŠΈλžœμž­μ…˜κ³Ό λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ€ λΆ„λ¦¬λ˜κΈ° λ•Œλ¬Έμ—, 영ν–₯을 μ„œλ‘œ 주지 μ•ŠμŠ΅λ‹ˆλ‹€. 

 

즉, μ™ΈλΆ€ νŠΈλžœμž­μ…˜κ³Ό λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ΄ 각각 λ³„λ„μ˜ 물리 νŠΈλžœμž­μ…˜μ„ κ°€μ§‘λ‹ˆλ‹€.

 

TestCode

@Test
void inner_rollback_REQUIRES_NEW()
{
    log.info("μ™ΈλΆ€ νŠΈλžœμž­μ…˜ μ‹œμž‘");
    TransactionStatus outer = transactionManager.getTransaction(new DefaultTransactionAttribute());
    log.info("outer.isNewTransaction() = {}", outer.isNewTransaction());

    innerRollback_requires_new();

    log.info("μ™ΈλΆ€ νŠΈλžœμž­μ…˜ 컀밋");
    transactionManager.commit(outer);
}

private void innerRollback_requires_new() {
    log.info("λ‚΄λΆ€ νŠΈλžœμž­μ…˜ μ‹œμž‘");

    DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
    definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

    TransactionStatus inner = transactionManager.getTransaction(definition);
    log.info("inner.isNewTransaction() = {}", inner.isNewTransaction());

    log.info("λ‚΄λΆ€ νŠΈλžœμž­μ…˜ λ‘€λ°±");
    transactionManager.rollback(inner);
}

1. μ™ΈλΆ€ νŠΈλžœμž­μ…˜ μ‹œμž‘

2. λ‚΄λΆ€ νŠΈλžœμž­μ…˜ μ‹œμž‘

3. λ‚΄λΆ€ νŠΈλžœμž­μ…˜ λ‘€λ°± - μ‹ κ·œ νŠΈλžœμž­μ…˜μ΄λ―€λ‘œ μ‹€μ œ rollback 호좜 

4. μ™ΈλΆ€ νŠΈλžœμž­μ…˜ 컀밋 - μ‹ κ·œ νŠΈλžœμž­μ…˜μ΄λ―€λ‘œ μ‹€μ œ commit 호좜

 

μ΅œμ’…μ μœΌλ‘œ μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ€ 컀밋, λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ€ λ‘€λ°±λ©λ‹ˆλ‹€.

 


<정리>

  • νŠΈλžœμž­μ…˜ μ „νŒŒλž€ ν•œ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ„ ν˜ΈμΆœν•˜λŠ” 경우λ₯Ό λ§ν•©λ‹ˆλ‹€.
  • 이 λ•Œ μ™ΈλΆ€ νŠΈλžœμž­μ…˜κ³Ό λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ€ 각각 논리 νŠΈλžœμž­μ…˜μ΄λΌ λΆ€λ₯΄κ³ , 이λ₯Ό λ¬Άμ–΄ 물리 νŠΈλžœμž­μ…˜μ΄λΌ λΆ€λ¦…λ‹ˆλ‹€.
  • λͺ¨λ“  논리 νŠΈλžœμž­μ…˜μ΄ μ»€λ°‹λ˜λŠ” κ²½μš°μ—λ§Œ 물리 νŠΈλžœμž­μ…˜μ΄ μ»€λ°‹λ©λ‹ˆλ‹€.
  • 단 ν•˜λ‚˜μ˜ 논리 νŠΈλžœμž­μ…˜μ΄λΌλ„ λ‘€λ°±λ˜λŠ” 경우 물리 νŠΈλžœμž­μ…˜μ΄ λ‘€λ°±λ˜μ–΄ λͺ¨λ“  논리 νŠΈλžœμž­μ…˜μ€ λ‘€λ°±λ©λ‹ˆλ‹€.
  • λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ€ μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ— μ°Έμ—¬ν•˜λŠ” 논리 νŠΈλžœμž­μ…˜μ΄κΈ° λ•Œλ¬Έμ—, commit을 ν˜ΈμΆœν•΄λ„ μ•„λ¬΄λŸ° λ™μž‘μ„ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • 반면, λ‚΄λΆ€ νŠΈλžœμž­μ…˜μ—μ„œ rollback을 ν˜ΈμΆœν•˜λŠ” 경우 νŠΈλžœμž­μ…˜λ§€λ‹ˆμ €μ— rollbackOnly μ˜΅μ…˜μ„ true둜 μ„€μ •ν•˜κΈ° λ•Œλ¬Έμ—, μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ€ 이 μ˜΅μ…˜μ΄ true둜 μ„€μ •λ˜μ–΄ 있으면 μ‹ κ·œ νŠΈλžœμž­μ…˜μ‘°κ±΄κ³Ό 상관없이 μ™ΈλΆ€ νŠΈλžœμž­μ…˜μ΄ commit λ˜λ”λΌλ„ 물리 νŠΈλžœμž­μ…˜ rollback을 ν˜ΈμΆœν•©λ‹ˆλ‹€.
    • rollbackOnly μ˜΅μ…˜μ΄ true둜 μ„€μ •λ˜μ–΄ 물리 νŠΈλžœμž­μ…˜μ΄ λ‘€λ°±λ˜λŠ” 경우, νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λŠ” UnexpectedRollbackException μ˜ˆμ™Έλ₯Ό 호좜 μ½”λ“œμ—κ²Œ λ‚΄λ˜μ§μœΌλ‘œμ¨, λͺ…ν™•ν•˜κ²Œ 문제λ₯Ό μ•Œλ €μ€λ‹ˆλ‹€.

<참고 자료>

 

Transaction μ „νŒŒκ°€ λ­‘λ‹ˆκΉŒ?

이전 ν¬μŠ€νŒ…μ—μ„œ Transactional을 ν•™μŠ΅ν•œ 이후에 Transactional μ „νŒŒμ— λŒ€ν•œ ν•™μŠ΅μ„ μ•½μ†ν–ˆκΈ° λ•Œλ¬Έμ— Transactional μ „νŒŒλΌλŠ” 주제둜 μΆ”κ°€ν•™μŠ΅μ„ μ§„ν–‰ν•˜κ²Œ 됐닀. μ–΄λ–€ νŠΈκ° μž­μ…˜μ΄ λ™μž‘μ€‘μΈ κ³Όμ •μ—μ„œ λ‹€λ₯Έ

velog.io

 

 

μŠ€ν”„λ§ DB 2편 - 데이터 μ ‘κ·Ό ν™œμš© 기술 - μΈν”„λŸ° | κ°•μ˜

λ°±μ—”λ“œ κ°œλ°œμ— ν•„μš”ν•œ DB 데이터 μ ‘κ·Ό κΈ°μˆ μ„ ν™œμš©ν•˜κ³ , μ™„μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μŠ€ν”„λ§ DB μ ‘κ·Ό 기술의 원리와 ꡬ쑰λ₯Ό μ΄ν•΄ν•˜κ³ , 더 κΉŠμ΄μžˆλŠ” λ°±μ—”λ“œ 개발자둜 μ„±μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€., - κ°•μ˜ μ†Œκ°œ | 인

www.inflearn.com

 

λΈ”λ‘œκ·Έμ˜ 정보

Study Repository

rlaehddnd0422

ν™œλ™ν•˜κΈ°