Skip to content

๐Ÿš€ ๋™์‹œ์„ฑ ์ด์Šˆ ์Šคํ„ฐ๋””

Notifications You must be signed in to change notification settings

SoA-Lee/Transaction-Lock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

2 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Concurrency Issue With Stock System

์žฌ๊ณ ์‹œ์Šคํ…œ์œผ๋กœ ์•Œ์•„๋ณด๋Š” ๋™์‹œ์„ฑ ์ด์Šˆ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

์ธํ”„๋Ÿฐ Inflearn - ์žฌ๊ณ ์‹œ์Šคํ…œ์œผ๋กœ ์•Œ์•„๋ณด๋Š” ๋™์‹œ์„ฑ ์ด์Šˆ ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ๊ฐ•์˜๋ฅผ ์ˆ˜๊ฐ•ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ๋ฐœ์ƒ ์ผ€์ด์Šค

ํ•˜๋‚˜์˜ ์ƒํ’ˆ์ด 100๊ฐœ์˜ ์žฌ๊ณ ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๋•Œ ๋‹จ์ˆœํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ํŒ๋งค๋  ๋•Œ ์žฌ๊ณ ๋ฅผ -1 ํ•œ ํ›„ ์ €์žฅํ•ด์ฃผ๋ฉด ๋ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์‹ค๋ฌด์—์„œ๋Š” ๋‹ค์–‘ํ•œ ์ผ€์ด์Šค๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

๋Œ€ํ‘œ์ ์œผ๋กœ, ํ•˜๋‚˜์˜ ์ƒํ’ˆ์— ์ฃผ๋ฌธ์ด ๋™์‹œ์— (ms ์ฐจ์ด ์ˆ˜์ค€) ๋“ค์–ด์˜จ๋‹ค๊ณ  ๊ฐ€์ •์„ ํ•œ๋‹ค. ์ด๋Ÿด ๋•Œ, Race Condition์ด ๋ฐœ์ƒํ•˜์—ฌ ๋งˆ์ง€๋ง‰ ์žฌ๊ณ  ๊ฐ’์ด ์ด์ƒํ•˜๊ฒŒ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

100๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ฐ™์€ ์ƒํ’ˆ์˜ ์žฌ๊ณ ๋ฅผ ๊ฐ์†Œ์‹œ์ผฐ์„ ๋•Œ ์ตœ์ข… ์žฌ๊ณ ๋Š” 0์„ ๊ธฐ๋Œ€ํ•˜์ง€๋งŒ ์‹ค์ œ ํ…Œ์ŠคํŠธ๋Š” ์‹คํŒจํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

1. Syncronized

Java์˜ ๊ธฐ๋ณธ Syncronized ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ์”ฉ ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค.

์˜ˆ์‹œ์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์“ฐ๋ ˆ๋“œ ๋™๊ธฐํ™”๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ฒฐ๊ณผ๋Š” ์‹คํŒจํ•œ๋‹ค. ์ด์œ ๋Š” @Transactiional Proxy ๋ฐฉ์‹ ๋•Œ๋ฌธ์— Proxy๊ฐ€ (Commit)์ข…๋ฃŒ๋˜๊ธฐ ์ „์— ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ํ•ด๋‹น ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ฐ’์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์„ ์ˆ˜ ์žˆ๋‹ค.

ํ•ด๊ฒฐ๋ฒ•

์„œ๋น„์Šค์— ๋ถ™์–ด์žˆ๋Š” @Transactional ์„ ์—†์•ค๋‹ค. @Transactional์„ ์ œ๊ฑฐํ•˜๋ฉด Proxy๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๊ธฐ ๋–„๋ฌธ์— ํ•ด๊ฒฐ์„ ํ•  ์ˆ˜๋Š” ์žˆ๋‹ค.

Syncronized ๋ฌธ์ œ์ 

Syncronized๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์—์„œ๋งŒ ๋™๊ธฐํ™”๋ฅผ ๋ณด์žฅํ•œ๋‹ค. ํ˜„๋Œ€์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ 2๋Œ€ ์ด์ƒ์˜ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Syncronized ๋กœ๋Š” ๋ณด์žฅํ•  ์ˆ˜ ์—†๋‹ค.

2. Mysql ์„ ํ™œ์šฉํ•œ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•

Pessimistic Lock์„ ํ™œ์šฉ

  • ์‹ค์ œ ๋ฐ์ดํ„ฐ์— Lock์„ ๊ฑธ์–ด์„œ ์ •ํ•ฉ์„ฑ์„ ๋งž์ถ”๋Š” ๋ฐฉ๋ฒ•
  • Exclusive Lock์„ ๊ฑธ๊ฒŒ๋˜๋ฉด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„ ๋Š Lock์ด ํ•ด์ œ๋˜๊ธฐ ์ „์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์—†๋‹ค.
  • Dead Lock์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•˜๊ธฐ
select stock0_.id as id1_0_, stock0_.product_id as product_2_0_, stock0_.quantity as quantity3_0_ from stock stock0_ where stock0_.id=? for update

select..for update ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น row๋ฅผ ๋‹ค๋ฅธ ์„ธ์…˜์—์„œ ๊ฑด๋“ค ์ˆ˜ ์—†๋„๋ก Lock์„ ๊ฑด๋‹ค.

์žฅ์ 
  • ์ถฉ๋Œ์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚˜๋ฉด Optimistic Lock๋ณด๋‹ค ์„ฑ๋Šฅ์ด ์ข‹์„ ์ˆ˜ ์žˆ์Œ
  • Lock์„ ์žก๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์„ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ์Œ
๋‹จ์ 
  • ์„ฑ๋Šฅ๊ฐ์†Œ

Optimistic Lock

  • ์‹ค์ œ Lock์„ ์ด์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฒ„์ „์„ ์ด์šฉํ•จ์œผ๋กœ์จ ์ •ํ•ฉ์„ฑ์„ ๋งž์ถ”๋Š” ๋ฐฉ๋ฒ•
  • ๋จผ์ € ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์€ ํ›„ update๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ ํ˜„์žฌ ๋‚ด๊ฐ€ ์ฝ์€ ๋ฒ„์ „์ด ๋งž๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ์—…๋ฐ์ดํŠธ
  • ๋‚ด๊ฐ€ ์ฝ์€ ๋ฒ„์ „์—์„œ ์ˆ˜์ •์‚ฌํ•ญ์ด ์ƒ๊ฒผ์„ ๊ฒฝ์šฐ application ๋‹จ์—์„œ ๋‹ค์‹œ ์ฝ์€ ํ›„ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•จ
์žฅ์ 
  • ๋ณ„๋„์˜ Lock์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ƒ ์ด์ 
๋‹จ์ 
  • ์‹คํŒจํ–ˆ์„ ์‹œ ๋กœ์ง์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋งŒ๋“ค์–ด์•ผํ•จ
  • ์ถฉ๋Œ์ด ๋นˆ๋ฒˆํžˆ ์ผ์–ด๋‚˜๋ฉด ์„ฑ๋Šฅ์ƒ ์†ํ•ด

Named Lock

  • ์ด๋ฆ„์„ ๊ฐ€์ง„ Metadata Locking (Table/Row Lock ์ด ์•„๋‹˜)
  • ์ด๋ฆ„์„ ๊ฐ€์ง„ Lock์„ ํš๋“ํ•œ ํ›„ ํ•ด์ œํ•  ๋•Œ ๊นŒ์ง€ ๋‹ค๋ฅธ ์„ธ์…˜์€ ์ด Lock ์„ ํš๋“ํ•  ์ˆ˜ ์—†๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • Transaction์ด ์ข…๋ฃŒ๋  ๋•Œ ์ž๋™์œผ๋กœ ํ•ด์ œ๋˜์ง€ ์•Š์Œ
  • ๋ณ„๋„์˜ ๋ช…๋ น์–ด๋กœ ํ•ด์ œ/์„ ์  ์‹œ๊ฐ„์ด ๋๋‚˜์•ผ ํ•ด์ œ Transaction์ด ์ข…๋ฃŒ๋  ๋•Œ Lock์ด ์ž๋™์œผ๋กœ ํ•ด์ œ๋˜์ง€ ์•Š์Œ.
ํŠน์ง•
  • JPA Native Query๋ฅผ ์ด์šฉ
  • Connction Pool ์ด ๋ถ€์กฑํ•ด์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ Datasource๋ฅผ ์ด์šฉํ•˜๊ธฐ๋ฅผ ์ถ”์ฒœ

3. Redis ํ™œ์šฉ

1. Lettuce

  • setnx ๋ช…๋ น์–ด ์‚ฌ์šฉ
  • spin lock ๋ฐฉ์‹
    • Lock์„ ํš๋“ํ•˜๋ ค๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ Lock์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ™•์ธํ•˜๋ฉด์„œ Lock ํš๋“ ์‹œ๋„
    • retry ๋กœ์ง ํ•„์š”
์žฅ์ 
  • ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•˜๋‹ค
  • spring data redis ๋ฅผ ์ด์šฉํ•˜๋ฉด lettuce ๊ฐ€ ๊ธฐ๋ณธ์ด๊ธฐ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
๋‹จ์ 
  • spin lock ๋ฐฉ์‹์ด๊ธฐ๋•Œ๋ฌธ์— ๋™์‹œ์— ๋งŽ์€ ์Šค๋ ˆ๋“œ๊ฐ€ lock ํš๋“ ๋Œ€๊ธฐ ์ƒํƒœ๋ผ๋ฉด redis ์— ๋ถ€ํ•˜๊ฐ€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
    • Thread.sleep์œผ๋กœ ๋ถ€ํ•˜๋ฅผ ์ค„์—ฌ์คฌ์Œ

2. Redisson

  • Pub-Sub ๊ธฐ๋ฐ˜์˜ Lock ๊ตฌํ˜„ ์ œ๊ณต
  • ์ฑ„๋„์„ ๋งŒ๋“ค๊ณ  Lock์„ ํš๋“ํ•œ Thread๊ฐ€ Lockํš๋“์„ ์‹œ๋„ํ•˜๋Š” Thread์—๊ฒŒ ํ•ด์ œ๋˜์—ˆ์Œ์„ ์•Œ๋ ค์ฃผ๋Š” ๋ฐฉ์‹
์žฅ์ 
  • ๋ฝ ํš๋“ ์žฌ์‹œ๋„๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค.
  • ๋ณ„๋„์˜ repository๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
  • pub-sub ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„์ด ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— lettuce ์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ redis ์— ๋ถ€ํ•˜๊ฐ€ ๋œ ๊ฐ„๋‹ค.
๋‹จ์ 
  • ๋ณ„๋„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
  • lock ์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฐจ์›์—์„œ ์ œ๊ณตํ•ด์ฃผ๊ธฐ ๋–„๋ฌธ์— ์‚ฌ์šฉ๋ฒ•์„ ๊ณต๋ถ€ํ•ด์•ผ ํ•œ๋‹ค.

์‹ค๋ฌด์—์„œ๋Š” ?

  • ์‹คํŒจ ์‹œ ์žฌ์‹œ๋„๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์€ lock ์€ lettuce ํ™œ์šฉ
  • ์‹คํŒจ ์‹œ ์žฌ์‹œ๋„๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” redisson ๋ฅผ ํ™œ์šฉ

์ถ”๊ฐ€ ์‚ฌํ•ญ

๐Ÿ“Œ ExecutorService

  • ExecutorService๋ž€, ๋ณ‘๋ ฌ ์ž‘์—… ์‹œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ œ๊ณต๋˜๋Š” JAVA ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.
  • ExecutorService๋Š” ์†์‰ฝ๊ฒŒ ThreadPool์„ ๊ตฌ์„ฑํ•˜๊ณ  Task๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • Executors ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ExecutorService ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉฐ, ์“ฐ๋ ˆ๋“œ ํ’€์˜ ๊ฐœ์ˆ˜ ๋ฐ ์ข…๋ฅ˜๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

๐Ÿ“Œ CountDownLatch

  • CountDownLatch๋ž€, ์–ด๋–ค ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ์—์„œ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ ๊ฐ€์ง€ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ํด๋ž˜์Šค๋‹ค.
  • CountDownLatch ๋ฅผ ์ด์šฉํ•˜์—ฌ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๊ฐ€ 100๋ฒˆ ์ž‘์—…์ด ๋ชจ๋‘ ์™„๋ฃŒํ•œ ํ›„, ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋„๋ก ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ํ•œ๋‹ค.

์ฐธ๊ณ  ์ž๋ฃŒ

https://github.com/dev-alxndr/concurrency-stock https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_exclusive_lock
https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html
https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html

About

๐Ÿš€ ๋™์‹œ์„ฑ ์ด์Šˆ ์Šคํ„ฐ๋””

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages