1. κ°œμš”

λ©€ν‹°μŠ€λ ˆλ“œ ν”„λ‘œκ·Έλž˜λ°μ΄λ‚˜ 닀쀑 νŠΈλžœμž­μ…˜μ„ μ²˜λ¦¬ν•˜λŠ” λ°μ΄ν„°λ² μ΄μŠ€ ν™˜κ²½μ—μ„œ κ°€μž₯ ν”Όν•˜κ³  싢은 문제 쀑 ν•˜λ‚˜κ°€ λ°”λ‘œ **λ°λ“œλ½(Deadlock, ꡐ착 μƒνƒœ)**μž…λ‹ˆλ‹€. 두 개 μ΄μƒμ˜ ν”„λ‘œμ„ΈμŠ€λ‚˜ νŠΈλžœμž­μ…˜μ΄ μ„œλ‘œκ°€ μ μœ ν•˜κ³  μžˆλŠ” μžμ›(Lock)을 기닀리며 λ¬΄ν•œνžˆ λŒ€κΈ°ν•˜λŠ” μƒνƒœλ₯Ό λ§ν•©λ‹ˆλ‹€. 이 κΈ€μ—μ„œλŠ” λ°λ“œλ½μ΄ μ™œ λ°œμƒν•˜κ³  μ–΄λ–»κ²Œ ν•΄κ²°ν•  수 μžˆλŠ”μ§€ 정리해 λ΄…λ‹ˆλ‹€.


2. λ°λ“œλ½μ˜ 4κ°€μ§€ λ°œμƒ 쑰건

λ°λ“œλ½μ΄ λ°œμƒν•˜λ €λ©΄ λ‹€μŒ 4κ°€μ§€ 쑰건이 λͺ¨λ‘ μΆ©μ‘±λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. ν•˜λ‚˜λΌλ„ κΉ¨μ§€λ©΄ λ°λ“œλ½μ€ λ°œμƒν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. (μ½”ν”„λ§Œ 쑰건, Coffman conditions)

  1. μƒν˜Έ 배제 (Mutual Exclusion): ν•œ λ²ˆμ— ν•œ ν”„λ‘œμ„ΈμŠ€λ§Œ ν•΄λ‹Ή μžμ›μ„ μ‚¬μš©ν•  수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. (DB의 배타 락)
  2. μ μœ μ™€ λŒ€κΈ° (Hold and Wait): μ΅œμ†Œν•œ ν•˜λ‚˜μ˜ μžμ›μ„ μ μœ ν•œ μƒνƒœμ—μ„œ λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€κ°€ μ μœ ν•˜κ³  μžˆλŠ” μžμ›μ„ μΆ”κ°€λ‘œ κΈ°λ‹€λ €μ•Ό ν•©λ‹ˆλ‹€.
  3. 비선점 (No Preemption): λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€κ°€ μ μœ ν•œ μžμ›μ„ κ°•μ œλ‘œ 뺏을 수 μ—†μ–΄μ•Ό ν•©λ‹ˆλ‹€.
  4. ν™˜ν˜• λŒ€κΈ° (Circular Wait): ν”„λ‘œμ„ΈμŠ€λ“€μ΄ μ›ν˜•μ„ 이루며 μ„œλ‘œμ˜ μžμ›μ„ λŒ€κΈ°ν•΄μ•Ό ν•©λ‹ˆλ‹€. (AλŠ” B의 μžμ›μ„, BλŠ” A의 μžμ›μ„ λŒ€κΈ°)

3. DB νŠΈλžœμž­μ…˜μ—μ„œμ˜ λ°λ“œλ½ μ‹œλ‚˜λ¦¬μ˜€

κ°€μž₯ ν”ν•˜κ²Œ λ°œμƒν•˜λŠ” DB λ°λ“œλ½μ€ μ„œλ‘œ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ΄ μ—‡κ°ˆλ¦° μˆœμ„œλ‘œ 락을 νšλ“ν•˜λ €κ³  ν•  λ•Œ λ°œμƒν•©λ‹ˆλ‹€.

sequenceDiagram
    participant Tx1 as νŠΈλžœμž­μ…˜ 1 (μ‚¬μš©μž A)
    participant Tx2 as νŠΈλžœμž­μ…˜ 2 (μ‚¬μš©μž B)
    participant ResA as μžμ› A (Account 1)
    participant ResB as μžμ› B (Account 2)

    Tx1->>ResA: 1. Lock νšλ“ (점유)
    Tx2->>ResB: 2. Lock νšλ“ (점유)
    Tx1->>ResB: 3. Lock μš”μ²­ (Tx2κ°€ ν•΄μ œν•  λ•ŒκΉŒμ§€ λŒ€κΈ°)
    Tx2->>ResA: 4. Lock μš”μ²­ (Tx1이 ν•΄μ œν•  λ•ŒκΉŒμ§€ λŒ€κΈ°)
    
    Note over Tx1,Tx2: πŸ’₯ λ¬΄ν•œ λŒ€κΈ° (Deadlock)

μœ„ μ‹œλ‚˜λ¦¬μ˜€μ—μ„œ Tx1은 ResBλ₯Ό 기닀리고, Tx2λŠ” ResAλ₯Ό 기닀리며 μ„œλ‘œκ°€ λλ‚˜κΈ°λ§Œμ„ μ˜μ›νžˆ κΈ°λ‹€λ¦½λ‹ˆλ‹€. RDBMSλŠ” 보톡 λ°λ“œλ½ 감지기(Deadlock Detector)κ°€ μžˆμ–΄μ„œ 이런 μ›ν˜• λŒ€κΈ°λ₯Ό κ°μ§€ν•˜λ©΄ νŠΈλžœμž­μ…˜ 쀑 ν•˜λ‚˜λ₯Ό λ‘€λ°±(Rollback)μ‹œμΌœ λ°λ“œλ½μ„ κΉΉλ‹ˆλ‹€.


4. λ°λ“œλ½ ν•΄κ²° 및 예방 방법

λ°λ“œλ½μ€ κ°μ§€ν•˜κ³  λ‘€λ°±μ‹œν‚€λŠ” λΉ„μš©μ΄ λͺΉμ‹œ 크기 λ•Œλ¬Έμ—, μ• μ΄ˆμ— λ°œμƒν•˜μ§€ μ•Šλ„λ‘ μ˜ˆλ°©ν•˜λŠ” 것이 κ°€μž₯ μ’‹μŠ΅λ‹ˆλ‹€.

4-1. μΌκ΄€λœ 락 νšλ“ μˆœμ„œ κ°•μ œ (Lock Ordering)

κ°€μž₯ ν™•μ‹€ν•œ 예방 λ°©λ²•μž…λ‹ˆλ‹€. ν™˜ν˜• λŒ€κΈ°(Circular Wait) 쑰건을 κΉ¨λœ¨λ¦¬λŠ” λ°©μ‹μž…λ‹ˆλ‹€. λͺ¨λ“  νŠΈλžœμž­μ…˜μ΄ 항상 같은 μˆœμ„œλ‘œ μžμ›(ν…Œμ΄λΈ”μ΄λ‚˜ λ ˆμ½”λ“œ)에 μ ‘κ·Όν•˜λ„λ‘ κ°•μ œν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μ—¬λŸ¬ κ³„μ’Œλ₯Ό μ—…λ°μ΄νŠΈν•΄μ•Ό ν•œλ‹€λ©΄ 항상 PK(ID)κ°€ μž‘μ€ μˆœμ„œλŒ€λ‘œ 락을 νšλ“ν•˜λ„λ‘ λ‘œμ§μ„ μž‘μ„±ν•©λ‹ˆλ‹€.

4-2. νŠΈλžœμž­μ…˜ λ²”μœ„ μ΅œμ†Œν™”

νŠΈλžœμž­μ…˜μ΄ κΈΈμ–΄μ§ˆμˆ˜λ‘ μžμ›μ„ μ μœ ν•˜λŠ”(Hold) μ‹œκ°„μ΄ κΈΈμ–΄μ§‘λ‹ˆλ‹€. μ™ΈλΆ€ API 호좜 λ“± μ‹œκ°„μ΄ 였래 κ±Έλ¦¬λŠ” μž‘μ—…μ€ νŠΈλžœμž­μ…˜ λ°–μœΌλ‘œ λΉΌκ³ , DB νŠΈλžœμž­μ…˜μ€ μ΅œλŒ€ν•œ μ§§κ³  κ°„κ²°ν•˜κ²Œ μœ μ§€ν•©λ‹ˆλ‹€.

4-3. 락 νƒ€μž„μ•„μ›ƒ (Lock Timeout) μ„€μ •

μ˜μ›νžˆ λŒ€κΈ°ν•˜λŠ” 것을 막기 μœ„ν•΄ 락을 κΈ°λ‹€λ¦¬λŠ” μ΅œλŒ€ μ‹œκ°„μ„ μ„€μ •ν•©λ‹ˆλ‹€. νƒ€μž„μ•„μ›ƒμ΄ λ°œμƒν•˜λ©΄ μ˜ˆμ™Έκ°€ λ˜μ Έμ§€κ³  νŠΈλžœμž­μ…˜μ΄ λ‘€λ°±λ˜μ–΄ λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€κ°€ 진행될 수 있게 ν•©λ‹ˆλ‹€.

λ°λ“œλ½μ€ μ‹œμŠ€ν…œμ΄ λ³΅μž‘ν•΄μ§ˆμˆ˜λ‘ λΉˆλ²ˆν•˜κ²Œ λ§ˆμ£ΌμΉ˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€. λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ 섀계할 λ•Œ **β€œμ–΄λ–€ μˆœμ„œλ‘œ μžμ›μ„ μž κΈ€ 것인가”**λ₯Ό 항상 κ³ λ―Όν•˜λŠ” μŠ΅κ΄€μ΄ ν•„μš”ν•©λ‹ˆλ‹€.