λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Spring

μ’‹μ•„μš” κΈ°λŠ₯을 톡해 μ‚΄νŽ΄λ³΄λŠ” λ™μ‹œμ„± 이슈 (synchronized)

by 주발2 2023. 2. 26.
λ°˜μ‘ν˜•

μ•ˆλ…•ν•˜μ„Έμš”, 이번 ν¬μŠ€νŒ…μ—μ„œλŠ” λ™μ‹œμ„±(Concurrency)에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

(예제 μ½”λ“œλŠ” κΉƒν—ˆλΈŒμ—μ„œ ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.)

 

 

λ™μ‹œμ„±(Concurrency) κ°œλ…

넀이버 사전에 검색해본 λ™μ‹œμ„±μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μ–΄λ–€ λ‘ μ‚¬κ±΄μ΄ κ°™μ€ μ‹œκ°„에 μΌμ–΄λ‚˜λŠ” κ²ƒμ„ μ΄λ₯΄λŠ” λ§

λŒ€λΆ€λΆ„μ˜ μ›Ή μ„œλ²„λŠ” μ—¬λŸ¬ 개의 μš”μ²­(ν΄λΌμ΄μ–ΈνŠΈ)을 λ™μ‹œμ— μˆ˜ν–‰ν•  수 있고, μ΄λŠ” μž‘μ„±ν•œ μ½”λ“œκ°€ λ™μ‹œμ— μˆ˜ν–‰λ  수 μžˆλ‹€λŠ” μ˜λ―Έμ™€ λ™μΌν•œ λ§₯λ½μž…λ‹ˆλ‹€.

 

μ΄λŸ¬ν•œ λ™μ‹œμ„± 문제λ₯Ό μ‚΄νŽ΄λ³΄κΈ° μœ„ν•΄ κ²Œμ‹œκΈ€μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈκ°€ λ™μ‹œμ— μ’‹μ•„μš”λ₯Ό ν–ˆμ„ λ•Œ λ°œμƒν•  수 μžˆλŠ” λ¬Έμ œμ— λŒ€ν•΄ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

μœ„ 그림에 λŒ€ν•œ μ„€λͺ…은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • User Aκ°€ κ²Œμ‹œκΈ€ 1에 μ’‹μ•„μš”λ₯Ό ν΄λ¦­ν–ˆμ„ λ•Œ likeCount 쑰회 (likeCount = 0)
  • User B도 κ²Œμ‹œκΈ€ 1에 μ’‹μ•„μš”λ₯Ό ν΄λ¦­ν–ˆμ„ λ•Œ likeCount 쑰회 (likeCount = 0)
    • BλŠ” Aκ°€ ν΄λ¦­ν•œ μž‘μ—…μ΄ 처리되기 μ „μ˜ 값을 μ‘°νšŒν–ˆμœΌλ―€λ‘œ μΉ΄μš΄νŠΈλŠ” 0
  • User Aκ°€ 클릭에 λŒ€ν•΄ commit을 ν•˜κ³ , 쑰회 수 + 1 증가 (likeCount = 1)
  • User B도 클릭을 톡해 commit을 ν•˜κ³ , 쑰회 수 + 1 증가 (likeCount = 1)

두 λͺ…μ˜ μ‚¬μš©μžκ°€ μ’‹μ•„μš”λ₯Ό ν΄λ¦­ν–ˆκΈ° λ•Œλ¬Έμ— μ΅œμ’… countλŠ” 2κ°€ λ˜μ–΄μ•Ό ν•˜μ§€λ§Œ, 각 μœ μ €κ°€ countλ₯Ό +1 ν•˜κΈ° μœ„ν•΄ μ‘°νšŒν–ˆμ„ λ•Œμ˜ 값은 λͺ¨λ‘ 0이기 λ•Œλ¬Έμ— 2κ°€ μ•„λ‹Œ 1이 μ¦κ°€λ˜κ³ , μ΅œμ’… κ²°κ³ΌλŠ” +1이 μ¦κ°€ν•˜μ—¬ 1이 λ˜λŠ” λ™μ‹œμ„± λ¬Έμ œκ°€ λ°œμƒν•©λ‹ˆλ‹€.

 

μœ„μ™€ 같은 상황을 경쟁 쑰건(race condition)이라고 ν•©λ‹ˆλ‹€.

경쟁 쑰건(race condition)
 - μ—¬λŸ¬ ν”„λ‘œμ„ΈμŠ€ 및 μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— λ™μΌν•œ 데이터(곡유 데이터)λ₯Ό μ‘°μž‘ν•  λ•Œ νƒ€μ΄λ°μ΄λ‚˜ μ ‘κ·Ό μˆœμ„œμ— 따라 μ˜ˆμƒν–ˆλ˜ κ²°κ³Όκ°€ λ‹¬λΌμ§ˆ 수 μžˆλŠ” 상황을 μ˜λ―Έν•©λ‹ˆλ‹€.

μ°Έκ³ : https://www.youtube.com/watch?v=vp0Gckz3z64&t=3s

μ‚¬μš©μžκ°€ μ’‹μ•„μš”λ₯Ό ν΄λ¦­ν•˜λŠ” 과정을 CPU levelμ—μ„œ λ΄€μ„λ•Œ Read-Modify-Write(쑰회-μˆ˜μ •-μ“°κΈ°) κ³Όμ •μ„ 톡해 μ΄λ£¨μ–΄μ§€κ²Œ λ©λ‹ˆλ‹€.

  • likeCountλ₯Ό Register둜 Loadν•˜κ³  (Read)
  • Register = Register + 1 (Modify)
  • Registerλ₯Ό likeCount에 Store ν•©λ‹ˆλ‹€. (Write)

 

 

λ™μ‹œμ„±(Concurrency) 이슈의 문제점

μœ„μ™€ 같은 λ™μ‹œμ„± μ΄μŠˆμ—λŠ” μ–΄λ– ν•œ λ¬Έμ œμ λ“€μ΄ μ‘΄μž¬ν• κΉŒμš”?

λŒ€λž΅μ μœΌλ‘œ μ•„λž˜μ™€ 같은 λ¬Έμ œμ λ“€μ΄ μ‘΄μž¬ν•  것 κ°™μŠ΅λ‹ˆλ‹€.

  • 곡유 데이터에 λŒ€ν•΄ μ˜ˆμƒ κ²°κ³Όκ°€ λ‹€λ₯΄μ§€λ§Œ 였λ₯˜κ°€ λ°œμƒν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • μ½”λ“œλ₯Ό μž‘μ„±ν•  λ•ŒλŠ” λ‘œμ»¬μ—μ„œ κ°œλ°œν•˜κΈ° λ•Œλ¬Έμ— νŒŒμ•…ν•˜κΈ°κ°€ νž˜λ“­λ‹ˆλ‹€.
  • λΉ„μ •ν˜•μ μœΌλ‘œ λ°œμƒν•˜κΈ° λ•Œλ¬Έμ— 디버깅이 νž˜λ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

μ½”λ“œλ‘œ μ‚΄νŽ΄λ³΄λŠ” λ™μ‹œμ„± 문제

전체 μ½”λ“œλŠ” κΉƒν—ˆλΈŒμ— μ‘΄μž¬ν•˜λ©°, κ°„λ‹¨ν•œ μ£Όμš” 둜직만 μ‚΄νŽ΄λ³΄λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

Post id = 1인 κ²Œμ‹œκΈ€μ˜ ν˜„μž¬ κ°’μž…λ‹ˆλ‹€.

 

curl λͺ…λ Ήμ–΄λ‘œ λ‹€μŒκ³Ό 같이 두 개의 μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€.

μ‹€ν–‰λœ 쿼리λ₯Ό 보면 update μΏΌλ¦¬λŠ” 총 두 κ°œμ΄μ§€λ§Œ, 이전에 μ‚΄νŽ΄λ³Έ μƒν™©μ²˜λŸΌ μ΅œμ’… κ²°κ³ΌλŠ” +1만 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

 

λ™μ‹œμ„± 문제 ν•΄κ²° - 1. synchronized

기쑴에 λ™μ‹œμ„± λ¬Έμ œμ™€ κ΄€λ ¨ν•΄μ„œ ν•΄κ²°ν•  수 μžˆλŠ” 방법 쀑 ν•˜λ‚˜λ‘œ λ©”μ„œλ“œμ— synchronized ν‚€μ›Œλ“œλ₯Ό μƒκ°ν•΄λ΄€μŠ΅λ‹ˆλ‹€.

 

λ©”μ„œλ“œμ— synchronizedλ₯Ό μ μš©ν•˜λ©΄ λ™μ‹œμ„± λ¬Έμ œλŠ” λ°œμƒν•˜μ§€ μ•Šμ„κΉŒμš”? ν…ŒμŠ€νŠΈλ₯Ό ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

(Serviceλ‚˜ Domainμ΄λ‚˜ 어디에 synchronizedλ₯Ό μΆ”κ°€ν•˜λ“  κ²°κ³ΌλŠ” λ™μΌν•˜κΈ°μ— μœ„μΉ˜λŠ” 크게 상관은 없을 것 κ°™μŠ΅λ‹ˆλ‹€.)

이전과 λ™μΌν•˜κ²Œ 두 번의 μš”μ²­μ„ λ³΄λƒˆμœΌλ‚˜ μ—¬μ „νžˆ λ™μ‹œμ„± λ¬Έμ œλŠ” λ°œμƒν•˜μ˜€κ³ , μ΅œμ’… κ²°κ³ΌλŠ” μœ„μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 1만 μ¦κ°€ν–ˆμŠ΅λ‹ˆλ‹€. 🧐

그럼 synchronizedκ°€ λ™μ‹œμ„± 문제λ₯Ό ν•΄κ²°ν•  수 μ—†λ‹€λŠ” κ²°κ³ΌμΈλ°μš”, μ–΄λ–»κ²Œ 된 κ±ΈκΉŒμš”?

 

μœ„μ— λŒ€ν•œ λ¬Έμ œλŠ” μ•„λž˜ Stackoverflowμ—μ„œ μ°Ύμ•„λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

 

μœ„ ν¬μŠ€νŒ…μ˜ λ‚΄μš©μ„ 쒅합해보면 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • νŠΈλžœμž­μ…˜(@Transactional)κ³Ό 동기화(synchronized)λŠ” μ„œλ‘œ λ‹€λ₯Έ κ°œλ…
  • νŠΈλžœμž­μ…˜μ€ Begin - 둜직 μ‹€ν–‰(count + 1) - Commit의 μˆœμ„œλ‘œ μ§„ν–‰λ˜λŠ”λ°, ν•˜λ‚˜μ˜ νŠΈλžœμž­μ…˜μ΄ 컀밋 되기 μ „ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ΄ 싀행될 수 있고, 이둜 인해 λ™μ‹œμ„± μ΄μŠˆκ°€ λ°œμƒ
  • synchronized ν‚€μ›Œλ“œλŠ” λ©”μ„œλ“œκ°€ ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œμ—μ„œλ§Œ μ‹€ν–‰ν•  수 μžˆλ„λ‘ Locking

 

synchronizedκ°€ μ²˜λ¦¬λ˜λŠ” 과정을 low-levelμ—μ„œ μ‚΄νŽ΄λ³΄λ©΄ λͺ¨λ‹ˆν„°(Monitor)λΌλŠ” κ°œλ…μ„ 톡해 동기화 과정이 μ΄λ£¨μ–΄μ§€κ²Œ λ©λ‹ˆλ‹€.

 

Monitor(λͺ¨λ‹ˆν„°)λŠ” 곡유 μžμ›μ— λŒ€ν•œ 접근을 μ œμ–΄ν•˜λŠ” 객체둜, ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ§Œ λ¦¬μ†ŒμŠ€μ— μ ‘κ·Όν•  수 μžˆλ„λ‘ 곡유 λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ 접근을 λ™κΈ°ν™”ν•˜λŠ”λ° μ‚¬μš©λ˜λŠ” κΈ°μˆ μž…λ‹ˆλ‹€.

νŠΈλžœμž­μ…˜κ³Ό synchronized의 λ™μ‹œμ„± λ°œμƒ 이슈(Monitor)

Monitor의 처리 과정은 μœ„μ™€ 같이 μŠ€λ ˆλ“œ λ‹¨μœ„λ‘œ λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” μ‹œμ μ—μ„œ λͺ¨λ‹ˆν„° 락을 νšλ“(acquire) 및 λ°˜ν™˜(release) ν•©λ‹ˆλ‹€.

Monitor에 λŒ€ν•œ μžμ„Έν•œ κ°œλ…μ€ μ•„λž˜ μ˜μƒμ— μžμ„Ένžˆ λ‚˜μ™€μžˆμœΌλ‹ˆ κΆκΈˆν•˜μ‹œλ©΄ μ˜μƒ & ν¬μŠ€νŒ…μ„ μ°Έκ³ ν•΄μ£Όμ„Έμš” πŸ™‚
  - https://youtu.be/Dms1oBmRAlo
  - https://happy-coding-day.tistory.com/8

 

λ”°λΌμ„œ Thread A의 νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ likePost() λ©”μ„œλ“œκ°€ μˆ˜ν–‰λœ ν›„ νŠΈλžœμž­μ…˜μ΄ 컀밋 되기 μ „ Thread B의 likePost() λ©”μ„œλ“œκ°€ 싀행이 되기 λ•Œλ¬Έμ— μ˜ˆμƒν–ˆλ˜ 바와 달리 synchronized ν‚€μ›Œλ“œλ₯Ό 톡해 λ™μ‹œμ„± 문제λ₯Ό ν•΄κ²°ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

(컀밋이 되기 μ „ Thread Bκ°€ 쑰회λ₯Ό ν–ˆκΈ° λ•Œλ¬Έμ— 언두(Undo) μ˜μ—­μ— μ‘΄μž¬ν•˜λŠ” countκ°€ μ¦κ°€ν•˜κΈ° 이전 값을 κ°€μ Έμ˜€κ²Œ λ©λ‹ˆλ‹€.)

* 언두(Undo)
언두 μ˜μ—­μ€ UPDATE λ¬Έμž₯μ΄λ‚˜ DELETE와 같은 λ¬Έμž₯으둜 데이터λ₯Ό λ³€κ²½ν–ˆμ„ λ•Œ λ³€κ²½λ˜κΈ° μ „μ˜ 데이터(이전 데이터)λ₯Ό λ³΄κ΄€ν•˜λŠ” κ³³μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ λ‹€μŒ 쿼리λ₯Ό μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.
MySQL > UPDATE member SET name = 'μ΄μ£Όν˜„' WHERE member_id = '5';
 
μœ„λ¬Έμž₯이 μ‹€ν–‰λ˜λ©΄ νŠΈλžœμž­μ…˜μ„ 컀밋 ν•˜μ§€ μ•Šμ•„λ„ μ‹€μ œ 데이터 파일 λ‚΄μš©μ€ "μ΄μ£Όν˜„"으둜 변경이 λ©λ‹ˆλ‹€. 그리고 λ³€κ²½λ˜κΈ° μ „μ˜ 값이 "홍길동"이라면 언두 μ˜μ—­μ—λŠ” "홍길동"μ΄λΌλŠ” 값이 백업이 λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 이 μƒνƒœμ—μ„œ λ§Œμ•½ μ‚¬μš©μžκ°€ 컀밋을 ν•˜κ²Œ 되면 ν˜„μž¬ μƒνƒœ(μ΄μ£Όν˜„)κ°€ κ·ΈλŒ€λ‘œ μœ μ§€λ˜κ³ , 둀백을 ν•˜κ²Œ λœλ‹€λ©΄ 언두 μ˜μ—­μ˜ λ°±μ—…λœ 데이터(홍길동)λ₯Ό λ‹€μ‹œ 데이터 파일둜 λ³΅κ΅¬ν•©λ‹ˆλ‹€.
 
μ΄λŸ¬ν•œ μ–Έλ‘μ˜ λ°μ΄ν„°λŠ” 크게 두 가지 μš©λ„λ‘œ μ‚¬μš©μ΄ λ©λ‹ˆλ‹€.
1) νŠΈλžœμž­μ…˜μ˜ λ‘€λ°± λŒ€λΉ„μš©
2) νŠΈλžœμž­μ…˜μ˜ 격리 μˆ˜μ€€μ„ μœ μ§€ν•˜λ©΄μ„œ 높은 λ™μ‹œμ„±μ„ 제곡

μœ„ 문제λ₯Ό ν•΄κ²°ν•˜λ €λ©΄ νŠΈλžœμž­μ…˜μ΄ 적용되기 μ „ λ‹¨κ³„μ—μ„œ synchronized ν‚€μ›Œλ“œλ₯Ό μ μš©ν•˜κ±°λ‚˜, @Transactional 제거λ₯Ό 톡해 λ™μ‹œμ„± 이슈λ₯Ό ν•΄κ²°ν•  수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€. λ³„λ‘œ 쒋은 방법은 μ•„λ‹Œ 것 κ°™μ§€λ§Œ, ν…ŒμŠ€νŠΈν•΄λ΄…μ‹œλ‹€.

 

 

1. νŠΈλžœμž­μ…˜μ΄ 적용되기 μ „ synchronized μ μš©ν•˜κΈ°

μ›ν•˜λŠ” λŒ€λ‘œ λ™μ‹œμ„± μ΄μŠˆλŠ” 해결이 λ˜μ—ˆμ§€λ§Œ, μ„±λŠ₯이 맀우 λΉ„νš¨μœ¨μ μΌ λ“― ν•©λ‹ˆλ‹€. (μ•„λž˜ 2번 μ°Έκ³ )

 

 

2. @Transactional 제거

μœ„μ˜ μ½”λ“œμ²˜λŸΌ @Transactional μ–΄λ…Έν…Œμ΄μ…˜μ„ μ œκ±°ν•˜λ©΄ μ˜ˆμƒν–ˆλ˜ κ²°κ³Όκ°€ λ‚˜μ˜€κΈ΄ ν•˜μ§€λ§Œ, synchronized둜 인해 λ©”μ„œλ“œμ˜ λͺ¨λ“  λ™μž‘μ— λŒ€ν•΄ Lock을 κ±Έμ–΄ ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ§Œ 접근이 κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— λ§Žμ€ μ˜€λ²„ν—€λ“œκ°€ λ°œμƒν•©λ‹ˆλ‹€.

 

μ•½ 1000번의 μš”μ²­λ§Œ λ°œμƒν•˜λ”λΌλ„ λŒ€λž΅ 11μ΄ˆκ°€ λ„˜λŠ” μ‹œκ°„μ΄ μ†Œμš”λ©λ‹ˆλ‹€.. 😱

synchronized ν‚€μ›Œλ“œλŠ” 또 λ‹€λ₯Έ λ¬Έμ œκ°€ μ‘΄μž¬ν•˜λŠ”λ°μš” μ΄λŠ” λ™μΌν•œ ν”„λ‘œμ„ΈμŠ€ λ‚΄μ˜ μŠ€λ ˆλ“œ λ‹¨μœ„μ—μ„œλ§Œ λ™μ‹œμ„±μ„ 보μž₯ν•©λ‹ˆλ‹€.

즉, 단일 μ„œλ²„λΌλ©΄ λ™μ‹œμ„± μ΄μŠˆκ°€ λ°œμƒν•˜μ§€ μ•Šκ² μ§€λ§Œ μ‹€μ§ˆμ μœΌλ‘œ μ›Ή ν™˜κ²½κ³Ό 같이 μ—¬λŸ¬ λŒ€μ˜ μ„œλ²„λ₯Ό ν™œμš©ν•˜λ©΄ λ™μ‹œμ„±μ„ 보μž₯ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

 

 

3. νŠΈλžœμž­μ…˜μ˜ 격리 μˆ˜μ€€μ„ SERIALIZABLE으둜 λ³€κ²½

μ„±λŠ₯은 맀우 λ–¨μ–΄μ§€κ² μ§€λ§Œ, 격리 μˆ˜μ€€μ΄ κ°€μž₯ 높은 SERIALIZABLEλ₯Ό μ„€μ •ν•˜λ©΄ ν•΄κ²°λ˜μ§€ μ•Šμ„κΉŒ? 라고 μƒκ°ν•˜μ—¬ ν…ŒμŠ€νŠΈλ₯Ό ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

(νŠΈλžœμž­μ…˜μ˜ 격리 μˆ˜μ€€μ— λŒ€ν•΄μ„œλŠ” ν•΄λ‹Ή ν¬μŠ€νŒ…μ„ μ°Έκ³ ν•΄ μ£Όμ„Έμš”.)

ν•˜μ§€λ§Œ Deadlock이 λ°œμƒν•˜λŠ”λ°μš”, μ΄λŠ” SERIALIZABLE의 νŠΉμ§•μ„ 생각해보면 이해할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

SERIALIZABLE의 격리 μˆ˜μ€€μ€ SELECT 쿼리가 μ‚¬μš©λ˜λŠ” λ ˆμ½”λ“œ(RECORD)에 λŒ€ν•΄ 읽기 락(Shared Lock)이 걸리게 λ©λ‹ˆλ‹€.

SELECT * FROM performance_schema.data_locks WHERE LOCK_TYPE = 'RECORD';

Shared Lock은 Lock을 얻은 μ„Έμ…˜μ—μ„œ 읽기만 κ°€λŠ₯ν•˜λ©° μ“°κΈ°(Insert, Update, Delete) λ“±μ˜ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

 

두 νŠΈλžœμž­μ…˜μ΄ λ™μΌν•œ 데이터(κ²Œμ‹œκΈ€ 1)에 λŒ€ν•΄ 읽기 락(Shared Lock)을 κ±Έκ³ , κ·Έ ν›„ μ„œλ‘œ μ“°κΈ° 락(Exclusive Lock)을 κ±ΈκΈ° λ•Œλ¬Έμ— Deadlock이 λ°œμƒν•©λ‹ˆλ‹€. (S-lock, X-lock의 경우 μ„œλ‘œ 양립할 수 μ—†κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.)

두 νŠΈλžœμž­μ…˜μ€ μ“°κΈ° 락을 κ±ΈκΈ° μœ„ν•΄ μ„œλ‘œ Lock이 ν•΄μ œλ˜κΈ°λ₯Ό λ¬΄ν•œνžˆ 기닀리며 Deadlock이 λ°œμƒν•˜κ²Œ λ©λ‹ˆλ‹€.

 

 

정리

μ΄μƒμœΌλ‘œ μ’‹μ•„μš” κΈ°λŠ₯을 톡해 λ™μ‹œμ„± μ΄μŠˆμ™€ 예제 μ½”λ“œ, Java의 synchronized ν‚€μ›Œλ“œ 등에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

synchronized ν‚€μ›Œλ“œλ₯Ό 톡해 λ™μ‹œμ„± 이슈λ₯Ό ν•΄κ²°ν•˜λŠ” 방법도 μ‘΄μž¬ν•˜μ§€λ§Œ, μ—¬λŸ¬ λŒ€μ˜ μ„œλ²„λ₯Ό ν™œμš©ν•˜λŠ” μ›Ή ν™˜κ²½μ—μ„œλŠ” μ‚¬μš©ν•˜κΈ°κ°€ νž˜λ“€ 것 κ°™μŠ΅λ‹ˆλ‹€.

 

λ‹€μŒμ—λŠ” λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ μ œκ³΅ν•˜λŠ” 낙관적 락(Optimistic Lock) 및 비관적 락(Pessimistic Lock)을 톡해 λ™μ‹œμ„±μ„ μ œμ–΄ν•˜λŠ” 방법에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

 

πŸ“„ μ°Έκ³ 

 

λ°˜μ‘ν˜•

λŒ“κΈ€