์ƒ์„ธ ์ปจํ…์ธ 

๋ณธ๋ฌธ ์ œ๋ชฉ

[๋™์‹œ์„ฑ ๋ฌธ์ œ] ๋‹ค์–‘ํ•œ ๊ธฐ๋ฒ•์„ ํ™œ์šฉํ•œ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ

๋ณธ๋ฌธ

๋™์‹œ์„ฑ ๋ฌธ์ œ ์˜ˆ์‹œ

Lost Update(๊ฐฑ์‹  ๋ถ„์‹ค)

๋‘ ๊ฐœ ์ด์ƒ์˜ ํŠธ๋žœ์žญ์…˜์ด ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ์ฝ๊ณ  ์ˆ˜์ •ํ•  ๋•Œ,

ํ•œ ํŠธ๋žœ์žญ์…˜์˜ ์ˆ˜์ • ๋‚ด์šฉ์ด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ์ˆ˜์ • ๋‚ด์šฉ์„ ๋ฎ์–ด์“ฐ๋Š” ํ˜„์ƒ

 

ex) ํŠธ๋žœ์žญ์…˜ A๊ฐ€ x = 10์„ ์ฝ๊ณ  x = 20์œผ๋กœ ์—…๋ฐ์ดํŠธ, ํŠธ๋žœ์žญ์…˜ B๊ฐ€ ๋™์‹œ์— x = 10 ์„ ์ฝ๊ณ  x = 30์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ›„ ์ปค๋ฐ‹ 

A์˜ ์—…๋ฐ์ดํŠธ ๊ฒฐ๊ณผ(20)๊ฐ€ B์˜ ์—…๋ฐ์ดํŠธ ๊ฒฐ๊ณผ(30)์œผ๋กœ ๋ฎ์—ฌ์“ฐ์—ฌ์ง

 

Dirty Read (๋ฐ˜์˜ ๋˜์ง€ ์•Š์€ ์ฝ๊ธฐ) ; ~ READ UNCOMMITED

ํŠธ๋žœ์žญ์…˜์ด ์•„์ง ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ์—ฐ์‚ฐ์— ์‚ฌ์šฉํ•จ.

์ด๋•Œ, ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ๋˜๋ฉด ์ฝ์—ˆ๋˜ ๊ฐ’์ด ์ž˜๋ชป๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋˜๋Š” ํ˜„์ƒ

 

ex) ํŠธ๋žœ์žญ์…˜ A๊ฐ€ x = 20์œผ๋กœ ์ˆ˜์ •ํ•œ ๋’ค ์ปค๋ฐ‹ํ•˜์ง€ ์•Š์Œ, ํŠธ๋žœ์žญ์…˜ B๊ฐ€ A์˜ ์ˆ˜์ •๋œ ๊ฐ’์„ ์ฝ๊ณ  x = 20 ๊ธฐ๋ฐ˜์œผ๋กœ ์—ฐ์‚ฐ ์ˆ˜ํ–‰. A๊ฐ€ ๋กค๋ฐฑ๋˜๋ฉด์„œ x = 10์œผ๋กœ ๋ณ€๊ฒฝ๋จ (ํŠธ๋žœ์žญ์…˜ B๋Š” ์ž˜๋ชป๋œ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉํ•œ ๊ฒŒ ๋จ)

 

Non-Repeatable Read (๋น„์ผ๊ด€์„ฑ ์ฝ๊ธฐ) ; ~READ COMMITTED

ํŠธ๋žœ์žญ์…˜์ด ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์ฝ์—ˆ๋Š”๋ฐ,

๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ๊ทธ ์‚ฌ์ด์— ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ์ฒ˜์Œ ์ฝ์—ˆ์„ ๋•Œ์™€ ๋‹ค๋ฅธ ๊ฐ’์„ ์ฝ๊ฒŒ ๋˜๋Š” ํ˜„์ƒ

 

ex) ํŠธ๋žœ์žญ์…˜ A๊ฐ€ x = 10์„ ์ฝ๊ณ , ์ดํ›„ ํŠธ๋žœ์žญ์…˜ B๊ฐ€ x = 20์œผ๋กœ ๊ฐ’์„ ์ˆ˜์ •ํ•œ ํ›„ ํŠธ๋žœ์žญ์…˜ A๊ฐ€ x ๋ฅผ ์ฝ์„ ๋•Œ, x = 20์„ ์ฝ๋Š” ํ˜„์ƒ

 

Phantom Read (ํŒฌํ…€ ์ฝ๊ธฐ) ; ~ REPEATABLE READ

ํŠธ๋žœ์žญ์…˜์ด ๋ฒ”์œ„ ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ํ–‰์„ ์ฝ์—ˆ์„ ๋•Œ, ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜์—ฌ ์ฝ์„ ๋ฐ์ดํ„ฐ์˜ ๋ฒ”์œ„๊ฐ€ ๋ฐ”๋€Œ๋Š” ํ˜„์ƒ

ํŠธ๋žœ์žญ์…˜ A๊ฐ€ ํŠน์ • ์กฐ๊ฑด์— ๋งž๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฝ๊ณ , ํŠธ๋žœ์žญ์…˜ B๊ฐ€ ํ•ด๋‹น ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•œ ํ›„,

ํŠธ๋žœ์žญ์…˜ A๊ฐ€ ๋‹ค์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ๋•Œ ์ƒˆ๋กœ์šด ๋ ˆ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋จ


Service-Level Locking

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ ๋ฝ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

synchronized, ReentrantLock, Semaphore ๋“ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

Semaphore

: ๋™์‹œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ž์›์˜ ์ˆ˜๋ฅผ ์ œํ•œํ•˜๋Š” ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜. ๋ฆฌ์†Œ์Šค ํ’€์ด๋‚˜ ์Šค๋ ˆ๋“œ ํ’€๊ณผ ๊ฐ™์€ ํ•œ์ •๋œ ์ž์›์„ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ์œ ์šฉํ•จ

ํŠน์ง• synchronized ReentrantLock Semaphore
๋ฝ ํš๋“/ํ•ด์ œ ๋ฐฉ์‹ ์ž๋™(์ž๋ฐ” VM์ด ๊ด€๋ฆฌ) ๋ช…์‹œ์ (lock()/unlock()) ๋ช…์‹œ์ (acquire()/release())
์žฌ์ง„์ž…์„ฑ ๋ถˆ๊ฐ€๋Šฅ ๊ฐ€๋Šฅ(์ž๊ธฐ ์ž์‹ ์ด ๋ฝ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํš๋“ ๊ฐ€๋Šฅ) ์—†์Œ
๋ฐ๋“œ๋ฝ ๋ฐฉ์ง€
X X X
์„ฑ๋Šฅ ๋‚ฎ์€ ์„ฑ๋Šฅ (๊ฒฝ์Ÿ ์ƒํƒœ ์‹œ ์„ฑ๋Šฅ ์ €ํ•˜) ๋†’์€ ์„ฑ๋Šฅ(๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ํšจ์œจ์ ) ์ž์› ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ ์„ฑ๋Šฅ์ด ๋‹ฌ๋ผ์ง
๋น„์ฐจ๋‹จ ๋ฝ ์ง€์› ์—†์Œ ๊ฐ€๋Šฅ(tryLock()) ๊ฐ€๋Šฅ(tryAcquire())
๊ธฐํƒ€ ๊ธฐ๋Šฅ ์—†์Œ ๊ณต์ •์„ฑ ์„ค์ •, ํƒ€์ž„์•„์›ƒ ๋“ฑ ์ž์› ์ œํ•œ ๊ฐœ์ˆ˜ ์กฐ์ •
  ๊ฐ„๋‹จํ•˜๊ณ  ์ž๋™์œผ๋กœ ๊ด€๋ฆฌ๋˜๋Š” ๋ฝ์„ ์‚ฌ์šฉํ•  ๋•Œ ์ ํ•ฉ
์„ฑ๋Šฅ์ด ์ค‘์š”ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋ฝ์ด ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ์— ์œ ์šฉ
ํƒ€์ž„์•„์›ƒ์„ ์„ค์ •ํ•˜๊ฑฐ๋‚˜
๋ฝ์„ ์‹œ๋„ํ•˜๊ณ  ์‹คํŒจํ–ˆ์„ ๋•Œ
๋‹ค๋ฅธ ์ž‘์—…์„ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ’€, ๋™์‹œ ์ ‘๊ทผ์ด ์ œํ•œ๋œ ์ž์› ๊ด€๋ฆฌํ•  ๋•Œ 

 


๋™์‹œ์„ฑ ์ œ์–ด ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ์•ˆ

๋น„๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด (Pessimistic Concurrency Control) 

์‹ค์ œ๋กœ ๋ฐ์ด์— Lock์„ ๊ฑธ์–ด์„œ ์ •ํ•ฉ์„ฑ์„ ๋งž์ถ”๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

execlusive lock์„ ๊ฑธ๊ฒŒ ๋˜๋ฉฐ, ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ๋Š” lock์ด ํ•ด์ œ๋˜๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.

๋ฐ๋“œ๋ฝ์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. 

์žฅ์ 
1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด์—์„œ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
2. ํŠธ๋žœ์žญ์…˜์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

๋‹จ์ 
ํŠธ๋ž˜ํ”ฝ์ด ๋†’์€ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฝ ๊ฒฝ์Ÿ์ด ์‹ฌํ•ด์ ธ ์ง€์—ฐ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1)  Row Lock (ํ–‰ ๋ฝ)

ํŠน์ • ํ–‰์— ๋Œ€ํ•ด์„œ ๋ฝ์„ ๊ฑธ์–ด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜๋“ค์ด ํ•ด๋‹น ํ–‰์„ ์ˆ˜์ •ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•œ๋‹ค.

-- ํ–‰ ๋ ˆ๋ฒจ ๋ฝ
SELECT * FROM users WHERE user_id = 1 FOR UPDATE;

 

2)  Table Lock (ํ…Œ์ด๋ธ” ๋ฝ)

ํ…Œ์ด๋ธ” ์ „์ฒด์— ๋ฝ์„ ๊ฑธ์–ด ๋™์‹œ์— ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•œ๋‹ค.

-- ํ…Œ์ด๋ธ” ๋ ˆ๋ฒจ ๋ฝ
LOCK TABLE users IN EXCLUSIVE MODE;

 

๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด (Optimistic Concurrency Control)

์—…๋ฐ์ดํŠธ ์ „์— ๋ฒ„์ „ ๋ฒˆํ˜ธ๋ฅผ ์ฒดํฌํ•˜๊ฑฐ๋‚˜ ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ํ™•์ธํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€ ํŒ๋ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๋ฐ์ดํ„ฐ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋กค๋ฐฑํ•˜๊ฑฐ๋‚˜ ๋‹ค์‹œ ์‹œ๋„ํ•œ๋‹ค.

 

JPA์—์„œ๋Š” @Version ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์—”ํ‹ฐํ‹ฐ์˜ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•œ๋‹ค.

@Entity
public class Product {
    @Id
    private Long id;

    @Version
    private Long version;

    private String name;
    private int price;
}

 

์ถฉ๋Œ์„ ์˜ˆ๋ฐฉํ•˜๋ฉด์„œ๋„ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๊ธฐ์— ๋‚™๊ด€์  ์ฒ˜๋ฆฌ์— ์ ํ•ฉํ•˜๋‹ค.

์ž์ฃผ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ํšจ์œจ์ ์ด๋‹ค.

์žฌ์‹œ๋„ ๋กœ์ง์ด ํ•„์š”ํ•˜๋‹ค. 

 


๋ถ„์‚ฐ ๋ฝ (Distributed Lock)

์„œ๋ฒ„๊ฐ€ ์—ฌ๋Ÿฌ ๋Œ€์ผ ๊ฒฝ์šฐ, ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ถ„์‚ฐ ๋ฝ์„ ์‚ฌ์šฉํ•œ๋‹ค.

Redis, ZooKeeper, Etcd์™€ ๊ฐ™์€ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฝ์„ ๊ด€๋ฆฌํ•œ๋‹ค.

 

Redis

- Lettuce

SETNX ๋ช…๋ น์–ด(set if not exists)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ์„œ๋ฒ„๋งŒ ์ž์›์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฝ์„ ๊ฑธ ์ˆ˜ ์žˆ๋‹ค.

Spin Lock ๋ฐฉ์‹์œผ๋กœ Retry ๋กœ์ง์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

- Redisson 

pub-sub ๊ธฐ๋ฐ˜์œผ๋กœ Lock ๊ตฌํ˜„์„ ์ œ๊ณตํ•œ๋‹ค.

pub-sub ๋ฐฉ์‹์ด๋ž€ ์ฑ„๋„์„ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ , ๋ฝ์„ ์ ์œ ์ค‘์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ํ•ด์ œํ–ˆ์Œ์„ ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ์— ์•Œ๋ ค์คŒ์œผ๋กœ์จ ๋Œ€๊ธฐ์ค‘์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ ์ ์œ ๋ฅผ ์‹œ๋„ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

 

ZooKeeper/Etcd: ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์—์„œ ์ž์›์˜ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์„œ๋ฒ„ ๊ฐ„์˜ ๋ฝ์„ ๊ด€๋ฆฌํ•œ๋‹ค.

// Redis์—์„œ ๋ถ„์‚ฐ ๋ฝ ๊ตฌํ˜„
Jedis jedis = new Jedis("localhost");
boolean isLockAcquired = jedis.setnx("lock_key", "locked") == 1;
if (isLockAcquired) {
    // ์ž‘์—… ์ˆ˜ํ–‰
    jedis.del("lock_key"); // ์ž‘์—… ์™„๋ฃŒ ํ›„ ๋ฝ ํ•ด์ œ
}

 

 

 

 

 

728x90

๊ด€๋ จ๊ธ€ ๋”๋ณด๊ธฐ