Pessimistic Locking vs. Optimistic Locking

  • 낙관적인 락, 비관적인 락.

  • λ“€μ–΄κ°€κΈ° 전에,

    • μ•„λ§ˆλ„ 락에 λŒ€ν•œ 처리λ₯Ό μ–΄λ–»κ²Œ 할지에 λŒ€ν•œ κ°œλ…μΌλ“―.

    • 락에 λŒ€ν•΄ λ‚™κ΄€μ μœΌλ‘œ μƒκ°ν•˜λŠλƒ, 락에 λŒ€ν•΄ λΉ„κ΄€μ μœΌλ‘œ μƒκ°ν•˜λŠλƒλ‘œ 이해됨.

About

  • 두가지 λͺ¨λ‘ Lock을 μ–΄λ–»κ²Œ λ‹€λ£° 것인가에 λŒ€ν•œ λͺ¨λΈ

    • λ°μ΄ν„°λ² μ΄μŠ€ κΈ°λ³Έ κΈ°λŠ₯은 μ•„λ‹Œλ“―. 즉 λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 기본적으둜 낙관적인 락 ν˜Ήμ€ 비관적인 락을 μ‚¬μš©ν•˜κ² λ‹€κ³  μ„ νƒν•˜λŠ” μ˜΅μ…˜μ€ μ—†λŠ”λ“―.

    • 단지 κ°œλ…μ μœΌλ‘œλŠ” 락(Lock)을 λ°”λΌλ³΄λŠ” 관점

  • 낙관적인 락

    • 비선점 잠금.

    • λ³€κ²½ 사항이 λ°μ΄ν„°λ² μ΄μŠ€μ— 컀밋될 λ•Œλ§Œ λ ˆμ½”λ“œκ°€ 잠길 κ²ƒμž„.

      • 락에 λŒ€ν•΄ 쑰금 λŠμŠ¨ν•˜κ²Œ λ°”λΌλ³΄λŠ” λ“―, νŠΈλžœμž­μ…˜ 간이 좩돌이 λ°œμƒν•˜μ§€ μ•Šμ„ 것.

      • 즉 락 섀정에 λ¬Έμ œκ°€ 없을 κ±°λ‹€!

    • 변경사항이 μžˆμ–΄λ„, 아직 컀밋이 μ•ˆλ˜μ—ˆμœΌλ©΄ μž κ²¨μžˆμ§€ μ•Šμ„λ“―.

  • 비관적인 락

    • μ…˜μ  잠금

    • λ ˆμ½”λ“œκ°€ 변경이 되고 μžˆλ‹€λ©΄, μž κ²¨μžˆμ„ κ±°μž„. 즉 Lock이 κ±Έλ € μžˆμ„ 것.

    • νŠΈλžœμž­μ…˜ κ°„ 좩돌이 일어날 것이라 μƒκ°ν•˜κ³  (비관적), 락을 μ’€ 미리 λΉ‘μ„Έκ²Œ κ±Έμ–΄λ†“λŠ” λŠλ‚Œ.

    • 낙관적인 락 λ³΄λ‹€λŠ” μ’€ 더 μ—„κ²©ν•œ λŠλ‚Œ.

    • λ§Œμ•½μ— μ–΄λ–€ λ ˆμ½”λ“œκ°€ μˆ˜μ • 쀑이라면 (아직 컀밋이 μ•ˆλœ μƒνƒœ) 락이 κ±Έλ €μžˆμ„ 거라 κΈ°λŒ€ν•˜λŠ” λͺ¨λΈμΈλ“―.

Optimistic locking

image
  • physical, logcial 적으둜 κ΅¬ν˜„μ΄ κ°€λŠ₯ν•œλ“―.

  • κ·Έλ ‡μ§€λ§Œ μ—¬λŸ¬λͺ¨λ‘œ Logical을 μ‚¬μš©ν•˜λŠ” 게 μ’€ 더 효율적으둜 λ³Ό 수 μžˆμ„λ“―

    • 즉 Database 자체 Lock λ³΄λ‹€λŠ”, 락 처럼 κ΅¬ν˜„ν•œ (Logical) κ±Έ μ‚¬μš©ν•˜λŠ”κ²Œ λ‚«λ‹€λŠ” μ˜λ―ΈμΈλ“―.

  • κ·Έλž˜μ„œ μœ„ 그림으둜 보면, version μ΄λΌλŠ” μ»¬λŸΌμ„ 톡해, Logcial Lock을 κ΅¬ν˜„ (JPAμ—μ„œ..)

    • commit μˆœκ°„ version 을 μ¦κ°€μ‹œν‚΄μœΌλ‘œμ¨, λ‹€λ₯Έ Update 문에 version = 1 쑰건이 λ˜μ–΄μžˆλŠ” ꡬ문은 λ¬΄μ‹œλ¨μ„ μ•Œ 수 있음.

    • 이럴 경우 PreapredStatement λŠ” 0을 λ¦¬ν„΄ν•˜κ³  data access framework (예λ₯Ό λ“€λ©΄ JPA..?) μ—μ„œλŠ” OptimisticLockException 을 던짐.

    • 그럴 경우 Alice κ°€ μ§„ν–‰ν•˜λ˜ Transaction 은 둀백됨.

    • μ μš©ν•˜λ €κ³  ν–ˆλ˜ update문에 λŒ€ν•œ 정보가 μ—†μ–΄μ§€λ‹ˆκΉŒ.. 이 뢀뢄에 λŒ€ν•œ μ²˜λ¦¬κ°€ application μ—μ„œ ν•„μš”ν•  지도..

In JPA

  • 보톡 μ—”ν‹°ν‹°μ˜ @Version ν•„λ“œλ₯Ό μ΄μš©ν•΄μ„œ μ‚¬μš©ν•¨.

  • κ·Έλž˜μ„œ μ—…λ°μ΄νŠΈ 전에, ν•΄λ‹Ή ν•„λ“œλ₯Ό μ²΄ν¬ν•˜λŠ” 방식을 이용

  • 4κ°€μ§€ Lock Modeλ₯Ό μ œκ³΅ν•˜κ³  있음.

    1. OPTIMISTIC

    2. optimistic read lock

    3. 비선점 락

    4. ν•΄λ‹Ή λͺ¨λ“œλ₯Ό μ‚¬μš©ν•˜λ©΄, dirty read or non-repeatable read κ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ λ§‰μ•„μ€Œ.

    5. 즉 μ»€λ°‹λ˜μ§€ μ•Šμ€ 데이터λ₯Ό μ½λŠ” 것을 λ°©μ§€ν•˜κ±°λ‚˜, ν•œ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ 같은 쿼리가 반볡 μ‹€ν–‰ 될 λ•Œ λ™μΌν•œ 값이 λ‚˜μ˜€λ„λ‘ 일관성을 보μž₯ν•΄μ€€λ‹€λŠ” 말.

    6. OPTIMISTIC_FORCE_INCREMENT

    7. OPTIMISTIC λ₯Ό 기반으둜, 좔가적인 버젼 μ¦κ°€λœ entityκ°€ λ°˜ν™˜λ¨.

    8. μ»€λ°‹μ΄λ‚˜ ν”ŒλŸ¬μ‹œ 되기 μ „κΉŒμ§€λŠ” μ—λŸ¬κ°€ λ°œμƒν• μ§€ νŠΉμ •ν•  수 μ—†μŒ.

    9. READ

    10. OPTIMISTIC의 alias

    11. WRITE

    12. OPTIMISTIC_FORCE_INCREMENT 의 alias

  • JPA μŠ€νŽ™μ—μ„œλŠ” READ, WRITE νƒ€μž…μ„ μ‚¬μš©ν•˜κΈ° λ³΄λ‹€λŠ” 1,2번 처럼 λͺ…μ‹œμ μΈ νƒ€μž…μ„ μ‚¬μš©ν•˜λŠ”κ±Έ ꢌμž₯ν•˜λŠ” λ“―.

  • λ°œμƒν•  수 μžˆλŠ” μ—λŸ¬

    • OptimisticLockException

    • ν•΄λ‹Ή μ—λŸ¬κ°€ λ˜μ Έμ‘Œμ„ λ•Œ, ν˜„μž¬ νŠΈλžœμž­μ…˜μ€ rollback only둜 mark됨.

    • 보톡 이 μ—λŸ¬λŠ”, λ‹€μ‹œ μ—”ν‹°ν‹°λ₯Ό μ‘°νšŒν•˜κ±°λ‚˜ (μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μœΌλ‘œ), κ·Έ 후에 μ—…λ°μ΄νŠΈ ν•˜λ„λ‘ ꢌμž₯됨.

  • μ •λ¦¬ν•˜μžλ©΄..

    • 기본적으둜 JPAμ—μ„œλŠ” OPTIMISTIC, OPTIMISTIC_FORCE_INCREMENT νƒ€μž…μ΄ 제곡되고 있음.

    • μ‚¬μš©λ°©λ²•μ€ Query μΈν„°νŽ˜μ΄μŠ€μ—μ„œ μ§€μ •ν•˜κ±°λ‚˜, μ—”ν‹°ν‹°λ§€λ‹ˆμ €λ₯Ό 톡해 μ΄μš©ν•˜λŠ” 방법도 μžˆλŠ”λ“―.

    • 그리고 보톡 μ—λŸ¬ λ°œμƒν•˜λ©΄, μΆ”κ°€μ μœΌλ‘œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 핸듀링이 ν•„μš”ν•œ κ²ƒμœΌλ‘œ 보이고.

    • λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ μ œκ³΅ν•˜λŠ” 락 (s lock, x lock) 을 μ‚¬μš©ν•˜λŠ” 것이 μ•„λ‹ˆλ―€λ‘œ, deadlock같은 상황이 λ°œμƒν•˜μ§€ μ•Šμ„ 것 κ°™μŒ.

Pessimistic lock

image
  • 비관적인 락

    • 즉 락이 걸릴 것을 μ˜ˆμƒν•˜κ³ , 미리 락을 선점함.

  • ν•˜λ‚˜μ˜ λ ˆμ½”λ“œμ— λ™μ‹œμ— μ—…λ°μ΄νŠΈκ°€ λ˜λŠ” 것을 막기 μœ„ν•΄ μ‚¬μš©λ¨.

  • μ–΄λ–€ μœ μ €κ°€ μ–΄λ–€ λ ˆμ½”λ“œμ— μ—…λ°μ΄νŠΈλ₯Ό μ‹€ν–‰ν•˜λ©΄, ν•΄λ‹Ή λ ˆμ½”λ“œμ—λŠ” 락이 걸리고, 이 락이 ν’€μ–΄μ§€κΈ° μ „(이 μ „ μœ μ €μ˜ 컀밋이 μ™„λ£Œλ  λ•Œ κΉŒμ§€) μ—λŠ” λ‹€λ₯Έ μœ μ €κ°€ ν•΄λ‹Ή λ ˆμ½”λ“œμ— μ—…λ°μ΄νŠΈλ₯Ό μ‹€ν–‰ν•  수 μ—†μŒ.

    • Shared, Exclusive lock..

    • μ‹€μ§ˆμ μœΌλ‘œ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ ν•΄λ‹Ή 행에 락을 건닀고 이해됨.

  • 락이 κ±Έλ €μžˆμ„ ν…Œλ‹ˆ, μΆ©λŒμ„ λ°©μ§€ν•  수 있음.

    • νŠΈλžœμž­μ…˜ κ°„ μΆ©λŒμ„ μ˜ˆλ°©ν•  수 있음.

    • κ·Έλ ‡μ§€λ§Œ μ„±λŠ₯μ μœΌλ‘œλŠ” λ³„λ‘œ μ•ˆ μ’‹μ§€ μ•Šμ„κΉŒ? (락을 κ±Έκ³ , ν™•μΈν•˜κ³  ν˜Ήμ€ ν‘ΈλŠ” 것 μžμ²΄κ°€ κ½€ λ¦¬μ†ŒμŠ€κ°€ μ†Œλͺ¨λ˜μ§€ μ•Šμ„κΉŒ 생각됨.)

    • μ™œ? 락을 κ±Έκ³ , ν’€κ³ , ν˜Ήμ€ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ—μ„œ ν•΄λ‹Ή λ ˆμ½”λ“œμ— 락이 κ±Έλ €μžˆλŠ” μ§€ ν™•μΈν•˜λŠ” μž‘μ—…μ΄ ν•„μš”ν•  ν…Œλ‹ˆ..

  • μœ„ μ²¨λΆ€λœ 그림을 보면, Bob의 UPDATE ꡬ문의 νŠΈλžœμž­μ…˜ 락은, Alice 의 컀밋이 μ™„λ£Œλ˜κΈ° μ „κΉŒμ§€λŠ” νšλ“ν•  수 μ—†μŒ.

    • 그런데 λ§Œμ•½μ— Aliceκ°€ commit이 μ–΄λ–€ μ΄μœ μ—μ„œ κ·ΈλŸ°μ§€ λλ‚˜μ§€ μ•ŠλŠ”λ‹€λ©΄..?

    • 일정 μ‹œκ°„μ΄ μ§€λ‚˜λ©΄ Dead Lock κ°™μ€κ²Œ λ°œμƒν•˜μ§€ μ•Šμ„κΉŒ?

In JPA

  • 3κ°€μ§€ LOCK MODE νƒ€μž…μ„ μ œκ³΅ν•˜κ³  있음.

    1. PESSIMISTIC_READ

    2. shared lock (s lock) μ‚¬μš©. κ·Έλž˜μ„œ ν•΄λ‹Ή row의 update or deleteλ₯Ό 방지함.

    3. dirty read λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄μ„œ μ‚¬μš©ν•¨.

    4. PESSIMISTIC_WRITE

    5. exclusive lock (x lock) μ‚¬μš©. read, update, deleted λͺ¨λ‘ λ§‰μŒ

    6. 즉 read, update, delete action을 ν•˜κΈ° μœ„ν•΄μ„œλŠ” 무쑰건 ν•΄λ‹Ή 락을 νšλ“ν•΄μ•Όλ¨.

    7. 단 μ–΄λ–€ λ°μ΄ν„°λ² μ΄μŠ€λŠ” ν•΄λ‹Ή 락을 μ‚¬μš©ν•˜κ³  μžˆμ–΄λ„, read ν•  수 μžˆλ„λ‘ μ§€μ›ν•΄μ£ΌλŠ” λ“― (MVCC)

    8. PESSIMISTIC_FORCE_INCREMENT

    9. PESSIMISTIC_WRITE λ₯Ό 기반으둜 entity의 version ν•„λ“œλ₯Ό μ΄μš©ν•΄ 버져닝 κΈ°λŠ₯도 지원

    10. @Version μ‚¬μš©

    11. update μ‹œμ—, 락 (x lock) νšλ“μ΄ ν•„μš”ν•œ λ™μ‹œμ—, version ν•„λ“œμ˜ 맀칭도 ν•„μš”ν•¨ (μ’€ 더 μ•ˆμ „ν•œλ“―.)

  • λ°œμƒν•  수 μžˆλŠ” μ—λŸ¬

    1. PessimisticLockException

    2. LockTimeoutException

    3. PersistanceException

    4. μœ„ μ—λŸ¬λ“€μ€ ν˜„μž¬ νŠΈλžœμž­μ…˜ μƒνƒœλ₯Ό rollback only μƒνƒœλ‘œ λ§Œλ“€μ–΄λ†“μŒ.

  • Lock Timeout μ…‹νŒ…

    • LockTimeoutException λ°œμƒμ„ μœ„ν•΄ 섀정이 ν•„μš”ν•œλ“―.

    • javax.persistence.lock.timeout 의 값을 μ΄μš©ν•˜λŠ” 데, λ‹¨μœ„λŠ” milliseconds

    • λ°μ΄ν„°λ² μ΄μŠ€κ°€ ν•΄λ‹Ή μ…‹νŒ…μ„ μ§€μ›ν•˜μ§€ μ•ŠλŠ” κ²½μš°λ„ μžˆμœΌλ‹ˆ, 확인이 ν•„μš”ν•¨.

  • μ •λ¦¬ν•˜μžλ©΄..

    • μ—¬λŸ¬ νŠΈλžœμž­μ…˜μ—μ„œ, 같은 λ¦¬μ†ŒμŠ€μ—μ„œ 같은 νƒ€μž„μ— μ ‘κ·Όν•˜μ§€ μ•Šλ„λ‘ λ°μ΄ν„°λ² μ΄μŠ€ μ°¨μ›μ—μ„œ 락을 μ΄μš©ν•΄μ„œ ν•΄κ²°ν•˜λŠ” 방법을 μ§€μ›ν•΄μ€Œ.

    • μ‚¬μš©λ°©λ²•μ€ μœ„μ—μ„œ μ–ΈκΈ‰ν•œ 것과 λΉ„μŠ· (Query, μ—”ν‹°ν‹°λ§€λ‹ˆμ €...λ“±λ“±)

    • λ°μ΄ν„°λ² μ΄μŠ€μ˜ 락을 μ‚¬μš©ν•˜λ‹ˆ, deadlock이 λ°œμƒν•  μˆ˜λ„ 있겠고, μ΄λŸ¬ν•œ 상황에 λŒ€μ²˜ν•˜κΈ° μœ„ν•΄μ„œ timeout 섀정이 ν•„μˆ˜μ μœΌλ‘œ λ³΄μž„.

좔가적인 ν‚€μ›Œλ“œ

  • Shared Lock, Exclusive Lock

  • Isolation Level

  • MVCC

  • Dead Lock

μ°Έκ³ 

Last updated

Was this helpful?