DB Concurrency Issue

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

[์ƒํ™ฉ: ํ™๊ธธ๋™ ๊ณ„์ขŒ ์ž”์•ก 10,000์›] (Lost Update)

  1. ํŠธ๋žœ์žญ์…˜ A: 3,000์› ์ž…๊ธˆ ์‹œ๋„. (DB ์กฐํšŒ: 10,000์› -> ๋ฉ”๋ชจ๋ฆฌ์—์„œ +3,000 = 13,000์›)

  2. ํŠธ๋žœ์žญ์…˜ B: 5,000์› ์ž…๊ธˆ ์‹œ๋„. (DB ์กฐํšŒ: 10,000์› -> ๋ฉ”๋ชจ๋ฆฌ์—์„œ +5,000 = 15,000์›)

  3. ํŠธ๋žœ์žญ์…˜ A ์ปค๋ฐ‹: DB์— 13,000์› ์ €์žฅ.

  4. ํŠธ๋žœ์žญ์…˜ B ์ปค๋ฐ‹: DB์— 15,000์› ์ €์žฅ. (13,000์›์„ ๋ฎ์–ด์”€)

๊ฒฐ๊ณผ: ์ตœ์ข… ์ž”์•ก์€ 15,000์›์ž…๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜ A๊ฐ€ ์ž…๊ธˆํ•œ 3,000์›์€ ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค.

๋‘ ํŠธ๋žœ์žญ์…˜์ด ๋ชจ๋‘ ์„ฑ๊ณต์ ์œผ๋กœ ์ปค๋ฐ‹์„ ํ–ˆ๋Š”๋ฐ๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์€ ๊นจ์กŒ์Šต๋‹ˆ๋‹ค.

์ฐจ๋ผ๋ฆฌ ์–ด๋”˜๊ฐ€ ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•ด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ์ฆ์ƒ์ด ์žˆ์—ˆ๋‹ค๋ฉด ๋ฌธ์ œ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ธ์ง€ํ•˜๊ณ  ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ, ๋’ค๋Šฆ๊ฒŒ ๋ฐœ๊ฒฌํ•œ ๊ฒฝ์šฐ ์ด๋ฏธ ์ผ๊ด€์„ฑ์ด ๋งŽ์ด ๊นจ์ ธ์žˆ์–ด์„œ ๊นจ์ง„ ์ผ๊ด€์„ฑ์„ ๋งž์ถ”๋Š” ๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

Dirty Read

ํ•œ ํŠธ๋žœ์žญ์…˜์ด ์•„์ง ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ์ˆ˜์ • ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ํ˜„์ƒ. ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•œ ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ๋  ๊ฒฝ์šฐ, ์ž˜๋ชป๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฒŒ ๋จ.

Non-Repeatable Read

ํ•œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ๋™์ผํ•œ ํ–‰(Row)๋ฅผ ๋‘ ๋ฒˆ ์ด์ƒ ์กฐํšŒํ–ˆ์„ ๋•Œ, ๊ทธ ์‚ฌ์ด์— ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์ปค๋ฐ‹ํ•˜์—ฌ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ๋‚˜ํƒ€๋‚˜๋Š” ํ˜„์ƒ.

Phantom Read

ํ•œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ํŠน์ • ๋ฒ”์œ„๋ฅผ ๋‘ ๋ฒˆ ์ด์ƒ ์กฐํšŒํ–ˆ์„ ๋•Œ, ๊ทธ ์‚ฌ์ด์— ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ํ•ด๋‹น ๋ฒ”์œ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€/์‚ญ์ œํ•˜๊ณ  ์ปค๋ฐ‹ํ•˜์—ฌ ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์ด ๋‹ฌ๋ผ์ง€๋Š” ํ˜„์ƒ.

Lost Update

๋‘ ๊ฐœ ์ด์ƒ์˜ ํŠธ๋žœ์žญ์…˜์ด ๋™์ผ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ์ˆ˜์ •ํ•  ๋•Œ, ๋‚˜์ค‘์— ์ปค๋ฐ‹ํ•œ ํŠธ๋žœ์žญ์…˜์˜ ์ˆ˜์ • ๋‚ด์šฉ์ด ๋จผ์ € ์ปค๋ฐ‹ํ•œ ํŠธ๋žœ์žญ์…˜์˜ ์ˆ˜์ • ๋‚ด์šฉ์„ ๋ฎ์–ด์จ์„œ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ์œ ์‹ค๋˜๋Š” ํ˜„์ƒ

ํ•ด๊ฒฐ์ฑ…: ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (Isolation Level) ์กฐ์ •

๊ฒฉ๋ฆฌ ์ˆ˜์ค€
Dirty Read
Non-Repeatable Read
Phantom Read
ํŠน์ง•

READ UNCOMMITTED

O

O

O

- ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๊ฒƒ์„ ํ—ˆ์šฉ - ์ •ํ•ฉ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋งŽ์•„ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ

READ COMMITTED

X

O

O

- ์ปค๋ฐ‹๋œ ๋ฐ์ดํ„ฐ๋งŒ ์ฝ๋„๋ก ํ•˜์—ฌ ๋”ํ‹ฐ ๋ฆฌ๋“œ๋ฅผ ๋ฐฉ์ง€. - ๋Œ€๋ถ€๋ถ„ ์ƒ์šฉ DB์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€

REPETABLE READ

X

X

O

- ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋œ ์‹œ์ ์˜ ๋ฐ์ดํ„ฐ ์Šค๋ƒ…์ƒท์„ ์ฝ์–ด, ํŠธ๋žœ์žญ์…˜ ๋‚ด๋‚ด ์ผ๊ด€๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์žฅ. - ๋…ผ ๋ฆฌํ”ผํ„ฐ๋ธ” ๋ฆฌ๋“œ๋ฅผ ๋ฐฉ์ง€. - MySQL InnoDB์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€

SERIALIZABLE

X

X

X

- ๊ฐ€์žฅ ์—„๊ฒฉํ•œ ์ˆ˜์ค€์œผ๋กœ, ํŠธ๋žœ์žญ์…˜์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰์‹œ์ผœ ๋ชจ๋“  ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€. - ๋™์‹œ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์ด ๊ฐ€์žฅ ๋‚ฎ์•„ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉ.

๊ฒฉ๋ฆฌ ์ˆ˜์ค€๊ณผ ์„ฑ๋Šฅ์€ ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„ ๊ด€๊ณ„์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ํŠธ๋žœ์žญ์…˜์€ ์–ด๋А ์ •๋„์˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ํ•„์š”ํ•œ์ง€ ๋”ฐ์ ธ๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ…: Pessimistic Lock

๋น„๊ด€์  ๋ฝ

  • ๊ฐœ๋…: "์ถฉ๋Œ์ด ๋ฌด์กฐ๊ฑด ๋ฐœ์ƒํ•  ๊ฑฐ์•ผ"๋ผ๊ณ  ๋น„๊ด€์ ์œผ๋กœ ์ƒ๊ฐํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ๋•Œ๋ถ€ํ„ฐ ์•„์˜ˆ ๋ฝ์„ ๊ฑธ์–ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.

  • SQL: SELECT ... FOR UPDATE ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘: ํŠธ๋žœ์žญ์…˜ A๊ฐ€ ํ™๊ธธ๋™ ๊ณ„์ขŒ๋ฅผ ์กฐํšŒํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฝ์„ ํš๋“ํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜ B๋Š” A๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ์กฐํšŒ๋ฅผ ๋ชป ํ•˜๊ณ  ๋Œ€๊ธฐ(Waiting) ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

  • ์žฅ์ : ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์„ ํ™•์‹คํ•˜๊ฒŒ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

  • ๋‹จ์ : ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๊ธธ์–ด์ ธ์„œ ์„ฑ๋Šฅ ์ €ํ•˜๋‚˜ **๋ฐ๋“œ๋ฝ(Deadlock)**์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Last updated