ํ”ผ๋“œ๋กœ ๋Œ์•„๊ฐ€๊ธฐ
Surviving Scale: How to Fix PostgreSQL Deadlocks in Laravel ๐Ÿ›‘
Dev.toDev.to
Database

Consistent Lock Ordering๊ณผ Retry ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•œ PostgreSQL Deadlock ํ•ด๊ฒฐ

Surviving Scale: How to Fix PostgreSQL Deadlocks in Laravel ๐Ÿ›‘

Prajapati Paresh2026๋…„ 4์›” 30์ผ3๋ถ„intermediate

Context

B2B SaaS ํ”Œ๋žซํผ์˜ ์„ฑ์žฅ์œผ๋กœ ์ธํ•œ High Concurrency ์ƒํ™ฉ์—์„œ Database Transaction์˜ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ์œ ์ง€ ์ค‘ Deadlock ๋ฐœ์ƒ. ์„œ๋กœ ๋‹ค๋ฅธ Transaction์ด ์ƒํ˜ธ ์˜์กด์ ์ธ Row Lock์„ ์ ์œ ํ•˜๋ฉฐ API ์š”์ฒญ ์‹คํŒจ์™€ 500 Server Error๋ฅผ ์œ ๋ฐœํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜์  ํ•œ๊ณ„ ๋…ธ์ถœ.

Technical Solution

  • ๋ฌด์ž‘์œ„ Lock ์ˆœ์„œ๋กœ ์ธํ•œ ๊ต์ฐฉ ์ƒํƒœ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด Row ID ๊ธฐ๋ฐ˜์˜ ์ผ๊ด€๋œ Lock ์ˆœ์„œ ๊ฐ•์ œ ์„ค๊ณ„
  • min/max ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ํ•ญ์ƒ ๋‚ฎ์€ ID์˜ Row๋ฅผ ๋จผ์ € Lock ํ•˜์—ฌ ์ˆ˜ํ•™์ ์œผ๋กœ Deadlock ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ์„ ์ œ๊ฑฐํ•œ Consistent Lock Ordering ์ ์šฉ
  • ์ธ๋ฑ์Šค ์—…๋ฐ์ดํŠธ๋‚˜ ๋ณต์žกํ•œ Cascade ์ž‘์—… ์ค‘ ๋ฐœ์ƒํ•˜๋Š” ์ผ์‹œ์  Deadlock ๋Œ€์‘์„ ์œ„ํ•ด Laravel์˜ Transaction Retry Helper ๋„์ž…
  • DB::transaction์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ํ†ตํ•ด ์ง€์ • ํšŸ์ˆ˜๋งŒํผ ์ž๋™ ์žฌ์‹œ๋„ ๋กœ์ง์„ ๊ตฌ์„ฑํ•˜์—ฌ ์‹œ์Šคํ…œ ํšŒ๋ณต ํƒ„๋ ฅ์„ฑ ํ™•๋ณด
  • ๋‹จ์ˆœํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ์•„๋‹Œ Transaction ์ „์ฒด ๋‹จ์œ„๋ฅผ ์žฌ์‹คํ–‰ํ•จ์œผ๋กœ์จ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ๊ณผ ๊ฐ€์šฉ์„ฑ์„ ๋™์‹œ์— ํ™•๋ณดํ•œ ๊ตฌ์กฐ

1. ๋‹ค์ค‘ Row ์—…๋ฐ์ดํŠธ ์‹œ ID ๊ธฐ๋ฐ˜ ์ •๋ ฌ ํ›„ Lock์„ ํš๋“ํ•˜๋Š” ์ˆœ์„œ ์ œ์–ด ๋กœ์ง ๊ตฌํ˜„ ์—ฌ๋ถ€ ๊ฒ€ํ† 

2. ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅํ•œ Transient Deadlock ๋ฐœ์ƒ ์ง€์ ์— ๋Œ€ํ•ด ์ ์ ˆํ•œ Retry ํšŸ์ˆ˜(์˜ˆ: 3ํšŒ) ์„ค์ • ์ ์šฉ

3. lockForUpdate() ์‚ฌ์šฉ ์‹œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ž ๊ธˆ ๋ฒ”์œ„์™€ ํŠธ๋žœ์žญ์…˜ ์œ ์ง€ ์‹œ๊ฐ„ ์ตœ์ ํ™”

์›๋ฌธ ์ฝ๊ธฐ