Chapter 2๋ฅผ ๋Œ์•„๋ณด๋ฉฐ - ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ํšŒ๊ณ  (5์ฃผ์ฐจ)

2024. 10. 25. 02:14ยท๐Ÿ  ์ผ์ƒ/๐Ÿ““ ์ผ์ƒ ์ผ๊ธฐ

 

๋“ค์–ด๊ฐ€๋ฉฐ

๋ฒŒ์จ ํ•ญํ•ด๋ฅผ ์‹œ์ž‘ํ•˜๊ณ  10์ฃผ ๊ณผ์ •์˜ ์ ˆ๋ฐ˜ ์ง€์ ์— ๋„์ฐฉํ–ˆ๋‹ค. ๋ณธ์—…๊ณผ ํ•จ๊ป˜ ๊ฐ•๋„ ๋†’์€ ๊ณผ์ œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์‰ฝ์ง€๋Š” ์•Š์•˜์ง€๋งŒ, ์ ˆ๋ฐ˜์ด ์ง€๋‚ฌ๋‹ค๋Š” ์ ์—์„œ ๋‚จ์€ ์ ˆ๋ฐ˜๋„ ๊ธˆ๋ฐฉ ์ž˜ ํ•ด๋‚ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. ์ง€๋‚œ 5์ฃผ ๋™์•ˆ ์šฐ๋ฆฌ ํŒ€ 5๋ช… ์ค‘ 3๋ช…์ด ์ดํƒˆํ–ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์ด ๋ณธ์—… ๋•Œ๋ฌธ์— ๊ณผ์ œ์— ์ง‘์ค‘ํ•˜๊ธฐ ์–ด๋ ค์› ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. ๋‹คํ–‰ํžˆ ๋‚˜์˜ ๊ฒฝ์šฐ ํšŒ์‚ฌ๊ฐ€ ๋ฐ”์œ ์‹œ์ฆŒ์ด ์•„๋‹ˆ์–ด์„œ (๋ฌผ๋ก  ๋ฐ”์˜์ง€ ์•Š์•„๋„ ํž˜๋“ค์ง€๋งŒ) ์—ฌ๊ธฐ๊นŒ์ง€ ๋ฒ„ํ‹ธ ์ˆ˜ ์žˆ์—ˆ๋‹ค.
 

๊ทธ๋ž˜๋„ ์—ด์‹ฌํžˆ ํ–ˆ์ž–์•„?

 
์ง€๋‚œ 3์ฃผ ๋™์•ˆ ๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋งŽ์€ ๊ฒƒ์„ ๋ฐฐ์šฐ๊ณ  ๊ฒฝํ—˜ํ–ˆ๋‹ค. ์ผ ๋๋‚˜๊ณ  ์ƒˆ๋ฒฝ 2~3์‹œ๊นŒ์ง€ ๊ณผ์ œ๋ฅผ ํ•˜๋ฉฐ ํ”ผ๊ณค์— ์ง€์ณ ์žˆ์—ˆ์ง€๋งŒ, ๋•๋ถ„์— ๋‹จ๊ธฐ๊ฐ„์— ํฐ ์„ฑ์žฅ์„ ์ด๋ฃฌ ๊ฒƒ ๊ฐ™๋‹ค. ์ด๋ฒˆ ํšŒ๊ณ ์—์„œ๋Š” ํ”„๋กœ์ ํŠธ Chapter 2(3~5์ฃผ์ฐจ)๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋ฐฐ์šด ์ ๋“ค๊ณผ, ์—ฌ์ „ํžˆ ๊ณ ๋ฏผ ์ค‘์ธ ๋ถ€๋ถ„๋“ค์„ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.
 
 

์‹œ๋‚˜๋ฆฌ์˜ค

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” ์ฝ˜์„œํŠธ ์ขŒ์„ ์˜ˆ์•ฝ ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. ์˜ˆ์•ฝ ์‹œ์Šคํ…œ์—์„œ๋Š” ๋Œ€๊ธฐ์—ด ๊ด€๋ฆฌ๊ฐ€ ๋งค์šฐ ์ค‘์š”ํ•œ ์š”์†Œ๊ณ , ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ์ขŒ์„์„ ์˜ˆ์•ฝํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๊ณต์ •ํ•˜๊ฒŒ ์˜ˆ์•ฝ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ขŒ์„ ์ƒํƒœ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด์—ˆ๋‹ค. ๊ฐ ๊ธฐ๋Šฅ๋งˆ๋‹ค์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์ƒ๊ฐ๋ณด๋‹ค ๋ณต์žกํ•˜๊ฒŒ ์–ฝํ˜€ ์žˆ์—ˆ๊ณ , ๋•๋ถ„์— ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๊ณ ๋ฏผ๊ณผ ์ƒˆ๋กœ์šด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‹œ๋„ํ•˜๋ฉด์„œ ๋ฌธ์ œ ํ•ด๊ฒฐ์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์ด ํ™•์žฅ๋œ ๋А๋‚Œ์„ ๋ฐ›์•˜๋‹ค.
 
 

๋ชฉํ‘œ

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์˜ ์ฃผ์š” ๋ชฉํ‘œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

1. ๋„๋ฉ”์ธ์— ๋Œ€ํ•œ ์ดํ•ด

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

 

2. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ๋ช…ํ™•ํ•œ ๋ถ„๋ฆฌ

์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ํด๋ฆฐ & ๋ ˆ์ด์–ด๋“œ ์•„ํ‚คํ…์ฒ˜์— ๋”ฐ๋ผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•˜๊ณ , ๊ฐ ๊ณ„์ธต์˜ ์—ญํ• ์„ ์ •์˜ํ–ˆ๋‹ค. ํ•˜์œ„์˜ ๋ ˆ์ด์–ด๋งŒ ์˜์กดํ•˜๋Š” ๋‹จ๋ฐฉํ–ฅ ์˜์กด์„ฑ์„ ์œ ์ง€ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ๋‹ค. ๋กœ์ง์ด ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ์—ญํ• ๊ณผ ์ฑ…์ž„์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ฐ์ฒด์ง€ํ–ฅ์  ์ ‘๊ทผ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ–ˆ๋‹ค.
 

3. ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ

์ขŒ์„ ์˜ˆ์•ฝ ์‹œ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋ฉฐ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์˜€๋‹ค. ๋„๋ฉ”์ธ ํŠน์„ฑ์„ ์ดํ•ดํ•˜๊ณ , ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ฏผํ–ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์œ ์ €์˜ ํฌ์ธํŠธ ์ถฉ์ „ ๋กœ์ง์—์„œ๋Š” ์ถฉ์ „์— ๋Œ€ํ•œ ์ˆœ์ฐจ ๋ณด์žฅ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•˜์—ฌ ๋‚™๊ด€์  ๋ฝ์„ ์‚ฌ์šฉํ•˜๊ณ , ์‹คํŒจํ•œ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ์žฌ์‹œ๋„ํ•˜์ง€ ์•Š๊ณ  ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.
 

4. ์ƒˆ๋กœ์šด ๊ธฐ์ˆ  ์Šต๋“

์ฝ”ํ‹€๋ฆฐ๊ณผ JPA ๊ฐ™์€ ์ƒˆ๋กœ์šด ๊ธฐ์ˆ ์„ ์‹ค๋ฌด์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€์œผ๋กœ ํ•™์Šตํ•˜๊ณ  ํ™œ์šฉํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•œ ๋ชฉํ‘œ ์ค‘ ํ•˜๋‚˜์˜€๋‹ค.
 
 
 

๋ฌธ์ œ ๋ฐ ์‹œ๋„, ํ•ด๊ฒฐ ๊ณผ์ •

 

1. ์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ ์ž‘์„ฑ

์ด๋ฒˆ์— ์ฒ˜์Œ์œผ๋กœ ์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ž‘์„ฑํ–ˆ๋‹ค. ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด์„œ ์ „์ฒด ํ๋ฆ„์„ ๋” ์ž˜ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ํŒ€์›๋“ค๊ณผ์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์—๋„ ํฐ ๋„์›€์ด ๋˜์—ˆ๋‹ค. ์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ํ†ตํ•ด ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํ˜ธ์ž‘์šฉ๊ณผ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ์ฝ”๋“œ ๊ตฌํ˜„์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„์„ ๋Œ€ํญ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์•ž์œผ๋กœ๋„ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•  ๊ณ„ํš์ด๋‹ค.
์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ ์ž‘์„ฑ GitHub ๋งํฌ
 

2. ๋Œ€๊ธฐ์—ด ์‹œ์Šคํ…œ์˜ ๊ตฌํ˜„๊ณผ ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ

๋Œ€๊ธฐ์—ด ์‹œ์Šคํ…œ์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ• ์ง€, ํŠนํžˆ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ์˜ˆ์•ฝ์„ ์‹œ๋„ํ•  ๋•Œ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ• ์ง€๊ฐ€ ํฐ ๊ณ ๋ฏผ์ด์—ˆ๋‹ค. Redis ๋Œ€์‹  RDB๋ฅผ ์‚ฌ์šฉํ•ด ๋Œ€๊ธฐ์—ด์„ ๊ตฌํ˜„ํ•˜๊ณ , ๋น„๊ด€์  ๋ฝ๊ณผ ๋‚™๊ด€์  ๋ฝ์„ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ ์šฉํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค. ์œ ์ €์˜ ํฌ์ธํŠธ ์ถฉ์ „ ๋กœ์ง์—๋Š” ๋‚™๊ด€์  ๋ฝ์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ถ€ํ•˜๋ฅผ ์ค„์ด๋ฉด์„œ๋„ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ–ˆ๊ณ , ์ขŒ์„ ์˜ˆ์•ฝ์ด๋‚˜ ๊ฒฐ์ œ ๋“ฑ์˜ ์ค‘์š”ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—๋Š” ๋น„๊ด€์  ๋ฝ์„ ์‚ฌ์šฉํ•ด ์ˆœ์„œ๊ฐ€ ๋ณด์žฅ๋˜๊ณ  ์ผ๊ด€์„ฑ ์žˆ๋Š” ๊ฒฐ๊ณผ๋ฅผ ์‘๋‹ตํ•˜๋„๋ก ์ž‘์„ฑํ–ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•๋“ค์„ ํ•™์Šตํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ธฐ
 

3. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ

์ข‹์€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ž€ ๋ฌด์—‡์ผ๊นŒ์— ๋Œ€ํ•ด ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ–ˆ๋‹ค. ๋‹จ์ˆœํžˆ ๊ธฐ๋Šฅ์ด ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€๋งŒ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋‹ค์–‘ํ•œ ์‹คํŒจ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ปค๋ฒ„ํ•  ์ˆ˜ ์žˆ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ๋‹ค. ์—ฃ์ง€ ์ผ€์ด์Šค์™€ ์‹คํŒจ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํฌ๊ด„ํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์„œ๋น„์Šค์˜ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜๊ณ ์ž ํ–ˆ๋‹ค.

 
 

4. ๋Œ€๊ธฐ์—ด ํ† ํฐ ๊ด€๋ฆฌ

๋Œ€๊ธฐ์—ด ํ† ํฐ ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•์œผ๋กœ ์œ ์ € ์ธ์ฆ๊ณผ ๋Œ€๊ธฐ์—ด ํ† ํฐ์˜ ๊ด€๊ณ„๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ์„ธ์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ ํ† ํฐ์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์„ ์‹œ๋„ํ–ˆ๋‹ค. ์ด๋Š” ์€ํ–‰์—์„œ ๋Œ€๊ธฐํ‘œ๋ฅผ ๋ฐ›๋“ฏ์ด ๋‹ค๋ฅธ ์œ ์ €์—๊ฒŒ ๋Œ€๊ธฐํ‘œ๋ฅผ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ํ–ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋” ์œ ์—ฐํ•œ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด user์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , token์œผ๋กœ ๋Œ€๊ธฐ์—ด์— ๋Œ€ํ•œ ์ƒํƒœ๋งŒ์„ ๊ด€๋ฆฌํ•˜๋„๋ก ํ–ˆ๋‹ค.

@Entity
class WaitingQueue(
    val scheduleId: Long,
    val token: String,
    status: QueueStatus,
    expiresAt: LocalDateTime?,
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0L,
) : BaseEntity() {
    @Enumerated(EnumType.STRING)
    var status: QueueStatus = status
        protected set

    var expiresAt: LocalDateTime? = expiresAt
        protected set

    fun expire() {
        status = QueueStatus.EXPIRED
    }

    fun activate(expireMinutes: Long) {
        this.status = QueueStatus.ACTIVE
        this.expiresAt = LocalDateTime.now().plusMinutes(expireMinutes)
    }
}

 

5. ์ฝ”ํ‹€๋ฆฐ์—์„œ์˜ JPA ์‚ฌ์šฉ

์ฝ”ํ‹€๋ฆฐ์œผ๋กœ JPA๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ์ƒˆ๋กœ์šด ๋„์ „์ด์—ˆ๋‹ค. ํŠนํžˆ ์—”ํ‹ฐํ‹ฐ ์„ ์–ธ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ธํ„ฐ๋„ท์„ ๊ฒ€์ƒ‰ํ•ด๋ณด๋ฉด ์˜๊ฒฌ์ด ๋ถ„๋ถ„ํ–ˆ๋Š”๋ฐ, ์ฝ”์น˜๋‹˜์˜ ์‹ค๋ฌด ๊ฒฝํ—˜์— ๋”ฐ๋ฅธ ์กฐ์–ธ์„ ๋ฐ”ํƒ•์œผ๋กœ ID๋ฅผ null ๋Œ€์‹  0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐฉ์‹์„ ์„ ํƒํ–ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด !! ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ๊ณ , JPA์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ๋„ ๋” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋™์ž‘ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค.

@Entity
class Concert(
    title: String,
    duration: Int,
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0L,
) : BaseEntity() {
    var title: String = title
        protected set

    var duration: Int = duration
        protected set
}

 
 

6. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต ๊ด€๋ฆฌ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต์€ ๊ฐ€๋Šฅํ•œ ์–‡๊ฒŒ ์œ ์ง€ํ•˜๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ๋„๋ฉ”์ธ์—์„œ ๋‘๊ป๊ฒŒ ์œ ์ง€ํ•˜๋ ค๊ณ  ํ–ˆ๋‹ค. ๋˜ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ง์ ‘ ๋„˜๊ฒจ๋ฐ›๋Š” ๋Œ€์‹  POJO ๊ฐ์ฒด๋ฅผ ์ฃผ๊ณ ๋ฐ›์œผ๋ฉฐ, ์—”ํ‹ฐํ‹ฐ ๋ณ€๊ฒฝ์€ ๋‚ด๋ถ€์—์„œ๋งŒ ์ด๋ฃจ์–ด์ง€๋„๋ก ํ–ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์˜ˆ์•ฝ ๊ฐ€๋Šฅ ์ขŒ์„ ์ˆ˜์— ๋Œ€ํ•œ ํ•„๋“œ ๊ฐ’ ๋ณ€๊ฒฝ ์‹œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

@Entity
class ConcertSchedule(
    val concertId: Long,
    startTime: LocalDateTime,
    totalSeats: Int,
    availableSeats: Int,
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0L,
) : BaseEntity() {
    
    ...
    
    fun occupySeat() {
        if (availableSeats <= 0) {
            throw CoreException(
                errorType = ErrorType.SEAT_UNAVAILABLE,
                message = "No available seats left to reserve.",
            )
        }
        this.availableSeats -= 1
    }

    ...
}

 

๋ฉ”์„œ๋“œ๋ช…์„ ๊ฐ€๋Šฅํ•œ ๋„๋ฉ”์ธ ๊ด€์ ์—์„œ์˜ ํ–‰์œ„๋ช…์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ–ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, decrementAvailableSeats() ๋Œ€์‹  occupySeat() ๊ฐ™์€ ํ–‰์œ„๋ช…์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์˜€๊ณ , ์ฝ”๋“œ์˜ ์˜๋ฏธ๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

7. ์—๋Ÿฌ ํ•ธ๋“ค๋ง

๊ธฐ์กด์—๋Š” ๊ฐœ๋ณ„์ ์œผ๋กœ ์ปค์Šคํ…€ ์˜ˆ์™ธ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ์ง€๋Š” ๋ฌธ์ œ์ ์ด ์žˆ์—ˆ๋‹ค.

 
 

์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ErrorType์„ ์ž‘์„ฑํ•˜๊ณ , ๊ฐ ์—๋Ÿฌ ์ฝ”๋“œ, ๋ฉ”์‹œ์ง€, ๋กœ๊ทธ ๋ ˆ๋ฒจ์„ ๋ถ€์—ฌํ•ด ํ•˜๋‚˜์˜ ์ปค์Šคํ…€ ์˜ˆ์™ธ๋กœ ์ฒ˜๋ฆฌํ–ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ErrorType์„ ์ •์˜ํ–ˆ๋‹ค.

enum class ErrorType(val code: ErrorCode, val message: String, val logLevel: LogLevel) {
    // common
    SYSTEM_FAILURE(SYSTEM_ERROR, "System encountered an unexpected error.", ERROR),
    TOKEN_EXPIRED(AUTHORIZATION_ERROR, "The token has expired.", WARN),

    // WaitingQueue
    INVALID_TOKEN(VALIDATION_ERROR, "Invalid or missing token.", WARN),
    QUEUE_ALREADY_EXISTS(QUEUE_ERROR, "A queue already exists for this token.", WARN),
    NO_QUEUE_FOUND(QUEUE_ERROR, "No queue found for the given token.", WARN),

    // Concert
    ...

    // User
    ...

    // Payment
    ...
}

class CoreException(
    val errorType: ErrorType,
    val details: Any? = null,
    message: String = errorType.message,
) : RuntimeException(message)

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

์•ž์œผ๋กœ ๊ฐœ์„ ํ•ด๋‚˜๊ฐˆ ์ 

 

1. ๋Œ€๊ธฐ์—ด ์‹œ์Šคํ…œ์˜ ๊ณ ๋„ํ™”

ํ˜„์žฌ๋Š” RDB์— ์ €์žฅ๋œ ํ† ํฐ์„ ์‚ฌ์šฉํ•ด ๋Œ€๊ธฐ์—ด์„ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์ง€๋งŒ, ์•ž์œผ๋กœ๋Š” ์„ฑ๋Šฅ ๋ฉด์—์„œ ๋” ๋น ๋ฅธ ์‘๋‹ต ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ ํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด Redis์™€ ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ ค ์ค‘์ด๋‹ค.
 

2. ํ…Œ์ŠคํŠธ ์ž‘์„ฑ

์ด๋ฒˆ ๊ณผ์ œ์—์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ด 77๊ฐœ ์ž‘์„ฑํ–ˆ๋‹ค. ์‹ค๋ฌด์—์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณธ ๊ฒฝํ—˜์ด ์—†์–ด์„œ ์ด ์ˆซ์ž๊ฐ€ ๋งŽ์€์ง€ ์ ์€์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ, ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ์ค‘์š”ํ•œ ์ ์„ ๊นจ๋‹ฌ์•˜๋‹ค. ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ์ฑ„์šฐ๊ธฐ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ, ์‹ค์ œ๋กœ ์‹œ์Šคํ…œ์˜ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ํ™”์ดํŠธ๋ฐ•์Šค ํ…Œ์ŠคํŠธ๋กœ ๋‚ด๋ถ€ ๋กœ์ง์„ ๊ฒ€์ฆํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•ด์•ผ ํ•˜๋ฉฐ, ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋Š” ๋ธ”๋ž™๋ฐ•์Šค ํ…Œ์ŠคํŠธ๋กœ ์™ธ๋ถ€์—์„œ์˜ ์ผ๊ด€์„ฑ์„ ๊ฒ€์ฆํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ์ฃผ์ œ๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ํ…Œ์ŠคํŠธ๋Š” ์ง€์–‘ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋‹ค์–‘ํ•œ ์—ฃ์ง€ ์ผ€์ด์Šค๋ฅผ ํ…Œ์ŠคํŠธํ•˜์—ฌ ์‹œ์Šคํ…œ์˜ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค.
 

3. ์„œ๋น„์Šค์˜ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•œ ์„ค๊ณ„

ํ˜„์žฌ์˜ ๊ตฌ์กฐ๊ฐ€ ์–ด๋А ์ •๋„์˜ ํŠธ๋ž˜ํ”ฝ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์„์ง€, ํ–ฅํ›„ ํŠธ๋ž˜ํ”ฝ ์ฆ๊ฐ€์— ์–ด๋–ป๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์„์ง€๋ฅผ ๊ณ ๋ คํ•ด๋ณด๊ณ  ๋ฐ˜์˜ํ•  ๊ณ„ํš์ด๋‹ค.
 
 
 

๋งˆ์น˜๋ฉฐ

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ๊ฐ€์žฅ ํฌ๊ฒŒ ๋А๋‚€ ๊ฒƒ์€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์ž์ฒด๋ณด๋‹ค ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•œ ์„ค๊ณ„์˜ ์ค‘์š”์„ฑ์ด์—ˆ๋‹ค. 3์ฃผ ๋™์•ˆ ์ˆ˜๋งŽ์€ ๊ณ ๋ฏผ๊ณผ ์‚ฝ์งˆ ์•„๋‹Œ ์‚ฝ์งˆ์„ ํ•˜๋ฉฐ, ๋‹จ์ˆœํžˆ ์ž‘๋™ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ '์ž˜ ์„ค๊ณ„๋œ ์ฝ”๋“œ'๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ๊นจ๋‹ซ๊ฒŒ ๋˜์—ˆ๋‹ค. ๋˜ํ•œ, ์ƒˆ๋กœ์šด ๊ธฐ์ˆ ์„ ์Šต๋“ํ•˜๊ณ  ์ด๋ฅผ ์ ์šฉํ•˜๋Š” ๊ณผ์ •์—์„œ ๋งŽ์€ ์„ฑ์žฅ์„ ์ด๋ฃจ์—ˆ๋‹ค.
 
์•„์ง ํ•ญํ•ด์˜ ๋ฐ˜์ด ๋‚จ์•˜์ง€๋งŒ ์กฐ๊ธˆ์”ฉ ์„ฑ์žฅํ•˜๊ณ  ์žˆ์Œ์„ ๋А๋ผ๊ณ  ์žˆ๊ณ , ํž˜๋“ค์ง€๋งŒ ๋™์‹œ์— ๋ฟŒ๋“ฏํ•จ๋„ ํฌ๋‹ค. ์•ž์œผ๋กœ ๋‚จ์€ ๊ธฐ๊ฐ„ ๋™์•ˆ๋„ ๊ณ„์†ํ•ด์„œ ๋ฐฐ์šฐ๊ณ , ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋” ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•  ๊ฒƒ์ด๋‹ค. ์ด ๊ณผ์ •์ด ๋๋‚  ๋•Œ์ฏค์—๋Š” ์ง€๊ธˆ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋‚˜์•„์ง„ ๋ชจ์Šต์„ ๊ธฐ๋Œ€ํ•˜๋ฉฐ, ๋๊นŒ์ง€ ์ตœ์„ ์„ ๋‹คํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.
 
 

์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'๐Ÿ  ์ผ์ƒ > ๐Ÿ““ ์ผ์ƒ ์ผ๊ธฐ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ์ตœ์ข… ํšŒ๊ณ  (+์ฃผ์ฐจ๋ณ„ ํ•™์Šต๋‚ด์šฉ ์ •๋ฆฌ)  (1) 2024.12.15
์š”๊ตฌ์‚ฌํ•ญ ๋ถ„์„(์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ, ERD, API ์„ค๊ณ„) - ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ํšŒ๊ณ  (3์ฃผ์ฐจ)  (2) 2024.10.15
Clean Architecture - ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ํšŒ๊ณ  (2์ฃผ์ฐจ)  (1) 2024.10.06
TDD, ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ - ํ•ญํ•ดย ํ”Œ๋Ÿฌ์Šค ํšŒ๊ณ  (1์ฃผ์ฐจ)  (3) 2024.09.29
ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ๋ฐฑ์—”๋“œ 6๊ธฐ - ํšŒ๊ณ  (0์ฃผ์ฐจ)  (1) 2024.09.22
'๐Ÿ  ์ผ์ƒ/๐Ÿ““ ์ผ์ƒ ์ผ๊ธฐ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ์ตœ์ข… ํšŒ๊ณ  (+์ฃผ์ฐจ๋ณ„ ํ•™์Šต๋‚ด์šฉ ์ •๋ฆฌ)
  • ์š”๊ตฌ์‚ฌํ•ญ ๋ถ„์„(์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ, ERD, API ์„ค๊ณ„) - ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ํšŒ๊ณ  (3์ฃผ์ฐจ)
  • Clean Architecture - ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ํšŒ๊ณ  (2์ฃผ์ฐจ)
  • TDD, ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ - ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ํšŒ๊ณ  (1์ฃผ์ฐจ)
EastShine_
EastShine_
๋” ๋‚˜์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ธฐ ์œ„ํ•œ ๋‚˜์˜ ๊ธฐ๋ก ๐Ÿ“
  • EastShine_
    ๊ฐœ๋ฐœ.LOG ๐Ÿ’ป
    EastShine_
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
  • 05-29 14:24
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (27)
      • ๐Ÿ’ป ๊ฐœ๋ฐœ (21)
        • ๐Ÿ–ฅ๏ธ ์šด์˜์ฒด์ œ (3)
        • ๐ŸŒ ๋„คํŠธ์›Œํฌ (0)
        • ๐Ÿ’พ Database (3)
        • ๐ŸŽ› Java (0)
        • ๐Ÿ–ฒ Javascript (0)
        • ๐Ÿ€ Spring (5)
        • ๐ŸŽธ ETC (4)
        • ๐Ÿ“ˆ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (3)
        • ๐Ÿ“– TIL (Today I Learned) (3)
      • ๐Ÿ  ์ผ์ƒ (6)
        • ๐Ÿ““ ์ผ์ƒ ์ผ๊ธฐ (6)
  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ๋ฐฑ์—”๋“œ
    ํšŒ๊ณ 
    ๋‚™๊ด€์ ๋ฝ
    ๋Œ€๊ธฐ์—ด
    Whisper API
    6๊ธฐ
    transactionaleventlistener
    ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
    ์ฝ˜์„œํŠธ์˜ˆ์•ฝ์„œ๋น„์Šค
    ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
    e-book pdf ์ถ”์ถœ
    ํŠธ๋žœ์žญ์…˜ ๋ถ„๋ฆฌ
    spring
    Python
    e-book pdf ๋ณ€ํ™˜
    ๋™์‹œ์„ฑ์ฒ˜๋ฆฌ
    ๋น„๊ด€์ ๋ฝ
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    redis
    ํ•ญํ•ดํ”Œ๋Ÿฌ์Šค
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.1
EastShine_
Chapter 2๋ฅผ ๋Œ์•„๋ณด๋ฉฐ - ํ•ญํ•ด ํ”Œ๋Ÿฌ์Šค ํšŒ๊ณ  (5์ฃผ์ฐจ)
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”