/images/profile.png

Spring Transaction ์˜ต์…˜

์ƒํ™ฉ ์Šคํ”„๋ง ํ™˜๊ฒฝ์—์„œ ์ผ๋ฐ˜์ ์œผ๋กœ DAO ๋‚˜ BO ๋ ˆ๋ฒจ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋”ฉ์„ ํ•˜๊ฒŒ ๋œ๋‹ค. @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public int method(int i) throws Exception { return sqlMapClient.delete("~~~~"); } ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ Ctrl+C,V ์‹ ๊ณต์œผ๋กœ ํŠธ๋žœ์žญ์…˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ ธ๋‹ค๊ฐ€ ์‚ฌ์šฉํ• ์ˆ˜๋„ ์žˆ๊ฒ ์œผ๋‚˜, ๊ฐ ๊ฐ’๋“ค์ด ์–ด๋–ค ์—ญํ™œ์„ ์•„๋Š”์ง€์— ๋Œ€ํ•ด ์•Œ๊ณ  ๋„˜์–ด๊ฐˆ ํ•„์š”์„ฑ์ด ์žˆ๋‹ค. @Transactional ์šฐ์„  ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•˜๋ฉด ์ ์šฉ๋œ ํด๋ž˜์Šค ๋˜๋Š” ๋ฉ”์†Œ๋“œ์— ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋กœ์ง ํ๋ฆ„์— ๋งž์ถ”์–ด ์ „์ฒด์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ• ๊ฒƒ์ธ์ง€, ์•„๋‹ˆ๋ฉด ํŠน์ • ๋ฉ”์†Œ๋“œ์— ์ ์šฉํ• ๊ฒƒ์ธ์ง€ ์ „๋žต์„ ์ž˜ ์„ธ์›Œ์•ผ ํ•œ๋‹ค. isolation ๊ฒฉ๋ฆฌ์ˆ˜์ค€์ด๋ผ๋Š” ์˜ต์…˜์ด๋‹ค. ํŠธ๋žœ์žญ์…˜์—์„œ ์ผ๊ด€์„ฑ์ด ์—†๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ—ˆ์šฉํ•˜๋„๋ก ํ•˜๋Š” ์ˆ˜์ค€์„ ๋งํ•˜๋Š”๋ฐ ์˜ต์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. READ_UNCOMMITTED (level 0) ํŠธ๋žœ์žญ์…˜์— ์ฒ˜๋ฆฌ์ค‘์ธ ํ˜น์€ ์•„์ง ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์ฝ๋Š” ๊ฒƒ์„ ํ—ˆ์šฉ ์–ด๋–ค ์‚ฌ์šฉ์ž๊ฐ€ A๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ B๋ผ๋Š” ๋ฐ์ดํ„ฐ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” B๋ผ๋Š” ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์€(Uncommitted ํ˜น์€ Dirty) ๋ฐ์ดํ„ฐ B๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค. Dirty read : ์œ„์™€ ๊ฐ™์ด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ์ž‘์—…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋Š”๋ฐ๋„ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ํ˜„์ƒ์„ dirty read ๋ผ๊ณ  ํ•˜๋ฉฐ, READ UNCOMMITTED ๊ฒฉ๋ฆฌ์ˆ˜์ค€์—์„œ๋งŒ ์ผ์–ด๋‚˜๋Š” ํ˜„์ƒ READ_COMMITTED (level 1) dirty read ๋ฐฉ์ง€ : ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋˜์–ด ํ™•์ •๋œ ๋ฐ์ดํ„ฐ๋งŒ์„ ์ฝ๋Š” ๊ฒƒ์„ ํ—ˆ์šฉ ์–ด๋– ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ A๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ B๋ผ๋Š” ๋ฐ์ดํ„ฐ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. REPEATABLE_READ (level 2) ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ SELECT ๋ฌธ์žฅ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ์— shared lock์ด ๊ฑธ๋ฆฌ๋ฏ€๋กœ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ๊ทธ ์˜์—ญ์— ํ•ด๋‹น๋˜๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์„ ํ–‰ ํŠธ๋žœ์žญ์…˜์ด ์ฝ์€ ๋ฐ์ดํ„ฐ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ํ›„ํ–‰ ํŠธ๋žœ์žญ์…˜์ด ๊ฐฑ์‹ ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์„ ๋ถˆํ—ˆํ•จ์œผ๋กœ์จ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‘ ๋ฒˆ ์ฟผ๋ฆฌํ–ˆ์„ ๋•Œ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•จ SERIALIZABLE (level 3) ์™„๋ฒฝํ•œ ์ฝ๊ธฐ ์ผ๊ด€์„ฑ ๋ชจ๋“œ๋ฅผ ์ œ๊ณต ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ ๋ฐ ๋™์‹œ์„ฑ์„ ์œ„ํ•ด MVCC(Multi Version Concurrency Control)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ(MVCC๋Š” ๋‹ค์ค‘ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ฑ๋Šฅ์„ ์œ„ํ•œ ๊ธฐ์ˆ ๋กœ ๋ฐ์ดํ„ฐ ์กฐํšŒ ์‹œ LOCK์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ์˜ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•ด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ ๋ฐ ๋™์‹œ์„ฑ์„ ๋†’์ด๋Š” ๊ธฐ์ˆ ) ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ SELECT ๋ฌธ์žฅ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ์— shared lock์ด ๊ฑธ๋ฆฌ๋ฏ€๋กœ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ๊ทธ ์˜์—ญ์— ํ•ด๋‹น๋˜๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ˆ˜์ • ๋ฐ ์ž…๋ ฅ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. propagation ( ์ „ํŒŒ์˜ต์…˜) REQUIRED : ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰ํ•˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ์—†์„ ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑ REQUIRES_NEW : ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์„ ๋ฌด์‹œํ•˜๊ณ  ๋ฌด์กฐ๊ฑด ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์ด ์ƒ์„ฑ SUPPORT : ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰ํ•˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ์—†์„ ๊ฒฝ์šฐ nontransactionally๋กœ ์‹คํ–‰ MANDATORY : ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ์—†์„ ๊ฒฝ์šฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ NOT_SUPPORT : nontransactionally๋กœ ์‹คํ–‰ํ•˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰๋  ๊ฒฝ์šฐ ์ผ์‹œ ์ •์ง€ NEVER : nontransactionally๋กœ ์‹คํ–‰๋˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ์กด์žฌํ•œ๋‹ค๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ NESTED : ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์—์„œ ์ง„ํ–‰๋  ๊ฒฝ์šฐ ๋ณ„๊ฐœ๋กœ ์ปค๋ฐ‹๋˜๊ฑฐ๋‚˜ ๋กค๋ฐฑ๋  ์ˆ˜ ์žˆ์Œ. ๋‘˜๋Ÿฌ์‹ผ ํŠธ๋žœ์žญ์…˜์ด ์—†์„ ๊ฒฝ์šฐ REQUIRED์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ no-rollback-for - ์˜ˆ์™ธ์ฒ˜๋ฆฌ (๊ธฐ๋ณธ๊ฐ’ : ์—†์Œ) ํŠน์ • ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋กค๋ฐฑ๋˜์ง€ ์•Š๋„๋ก ์„ค์ • ์Šคํ”„๋ง ๋ฐฐ์น˜์—์„œ์˜ ํŠธ๋žœ์žญ์…˜ (๋‚ด๊ฐ€ ๋‹นํ–ˆ๋˜(?) ๋ฌธ์ œ) ์Šคํ”„๋ง ๋ฐฐ์น˜์—์„œ๋Š” Tasklet ์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ step ๋‹จ์œ„ ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ job์ด ํ•˜๋‚˜์˜ tasklet ์˜ step ์œผ๋กœ ์‹คํ–‰ํ•˜๋‹ค๋ณด๋‹ˆ ๋ช…์‹œ์ ์ด์ง„ ์•Š์ง€๋งŒ ๋‚ด๋ถ€์ ์œผ๋กœ ์ „์ฒด ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๊ฑธ๋ ค์žˆ๊ฒŒ ๋œ๋‹ค. ๋‚˜๊ฐ™์€ job ๋‚ด DAO delete ๋ฉ”์†Œ๋“œ์—์„œ @Transactional ์„ค์ •์„ ํ•˜๊ณ  ๊ทธ DAO ๋ฉ”์†Œ๋“œ๋ฅผ ๋ฐ˜๋ณต๋ฌธ์— ์˜ํ•ด delete ํ•˜๋Š” ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์—ˆ๋Š”๋ฐ ๋ถ€๋ชจ์˜ ํŠธ๋žœ์žญ์…˜(tasklet์—์„œ ์„ค์ •๋œ ํŠธ๋žœ์žญ์…˜)์œผ๋กœ ์ธํ•ด dao ๋ฅผ ๋ช‡๋ฒˆ ํ˜ธ์ถœํ•˜๋˜ job๋‹จ์œ„๋กœ ํŠธ๋ Œ์ ์…˜์ด ๊ฑธ๋ฆฌ๊ฒŒ ๋˜์—ˆ๋‹ค. (๊ฒฐ๊ตญ ํŠธ๋žœ์žญ์…˜์€ ๋ฐ˜๋ณต๋ฌธ์ด ๋‹ค ๋๋‚˜์•ผ ์ ์šฉ์ด ๋œ๋‹ค๋Š”์ .) ๊ทธ๋Ÿฌ๋‹ค๋ณด๋‹ˆ ๊ฐ€๋” DB Query Lock์ด ๊ฑธ๋ ธ๋Š”๋ฐ DB๋ ˆ๋ฒจ์—์„œ undolog๋ฅผ ๋‚จ๊ธฐ๋Š”๊ฒŒ ๋„ˆ๋ฌด ๋ฌด๊ฑฐ์›Œ์ ธ lock์ด ๋ฐœ์ƒ ๋”ฐ๋ผ์„œ ์ „ํŒŒ์˜ต์…˜์„ ์ˆ˜์ •ํ•ด์„œ ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€๋‹ค. # ๊ธฐ์กด begin delete < for ๋ฐ˜๋ณต๋ฌธ commit # ์ „ํŒŒ์˜ต์…˜ ์ˆ˜์ • (๊ธฐ์กด REQUIRES ์—์„œ REQUIRES_NEW ์œผ๋กœ ์ˆ˜์ •) for begin delete commit for end

๋””์ž์ธํŒจํ„ด-์‹ฑ๊ธ€ํ†ค

๋””์ž์ธ ํŒจํ„ด์ค‘์— ๊ฐ€์žฅ ์ž˜ ์•Œ๋ ค์ง„ ์‹ฑ๊ธ€ํ†ค ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ณ ์ž ํ•œ๋‹ค. ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์ž์ฃผ ์ด์šฉ๋˜๋Š” ํŒจํ„ด์ด๋ผ๊ณ ๋งŒ ๋“ค์—ˆ๋Š”๋ฐ ์ด๋ฒˆ ๊ธฐํšŒ๋ฅผ ํ†ตํ•ด ์ œ๋Œ€๋กœ ์ •๋ฆฌํ•ด๋ณด์ž ์‹ฑ๊ธ€ํ†ค์ด ๋ฌด์—‡์ธ๊ฐ€ ์‹ฑ๊ธ€ํ†ค(Singleton)์€ ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ ์ƒ์„ฑ๋˜๋Š” ํด๋ž˜์Šค์ด๋‹ค. ๋ผ๊ณ  ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”์—์„œ ์ •์˜๋˜์–ด์žˆ๋‹ค. ์ฆ‰, ๋”ฑ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ ์—ฌ๊ธฐ์ €๊ธฐ์„œ ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด์ด๋ผ ์ƒ๊ฐํ•˜๋ฉด ๋ ๋“ฏ ํ•˜๋‹ค. ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋‹น์—ฐํžˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ•  ์ƒํ™ฉ์ด ์—†๊ฒ ์ง€๋งŒ ๋Œ€๋ถ€๋ถ„ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์€ ์•„์ฃผ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด๋‹ค. ์•„์ฃผ ๊ณ ์ „์ ์ธ ๋ฐฉ๋ฒ• (์œ„ํ—˜ํ•œ ๋ฐฉ๋ฒ•) public class Singleton { private static Singleton uniqueInstance; private Singleton(){} public static Singleton getInstance(){ if (uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } } ์œ„์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ if์ ˆ์„ ๋„๋‹ฌํ•˜๋Š” ์‹œ์ ์ด ๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ๋‹ค๋ฅผ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.(๊ต๋ฌ˜ํ•œ ์‹œ์ ์— ๊ฐ์ฒด๊ฐ€ 1๊ฐœ ์ด์ƒ ๋ฐ˜ํ™˜๋  ์—ฌ์ง€๊ฐ€ ์žˆ์Œ) ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด getInstance()๋ฅผ ๋™๊ธฐํ™” ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ํ•˜์ง€๋งŒ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋™๊ธฐํ™” ํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๋งŒ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค. public class Singleton { private static Singleton uniqueInstance; private Singleton(){} public static synchronized Singleton getInstance(){ if (uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } } public static ์ธ์Šคํ„ด์Šค๋กœ ์ƒ์„ฑ public static final LocalCache sharedObject = new LocalCache(); private LocalCache() { } ์ด์ฝ”๋“œ๋Š” ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋Š” ๋ฐ˜๋ฉด์— ์œ ์—ฐํ•˜์ง€ ๋ชปํ•œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค. (์•„๋ž˜ ์ด์–ด์„œ ์„ค๋ช…) private static final ์ธ์Šคํ„ด์Šค๋กœ ์ƒ์„ฑ private static final LocalCache sharedObject = new LocalCache(); private LocalCache() { } public static LocalCache getInstance() { return sharedObject ; } ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด factory ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜๋ฐ›๊ณ , ๋ฐ˜ํ™˜ ๋ฐ›๋Š” ์‹œ์ ์— ๋‹ค์–‘ํ•œ ์ž‘์—…๋“ค์„ ํ• ์ˆ˜ ์žˆ๋‹ค. enum ์œผ๋กœ ์ƒ์„ฑ public enum LocalCacheEnum { LocalCache; //etc another functions } ์ž˜ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๊ฐ€์žฅ ์ข‹์€ ์„ธ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์ธ enum์œผ๋กœ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ•œ๋‹ค. ๋ณต์žกํ•œ ์ง๋ ฌํ™”๋‚˜ ๋ฆฌํ”Œ๋ ‰์…˜(reflection) ์ƒํ™ฉ์—์„œ๋„ ์ง๋ ฌํ™”๊ฐ€ ์ž๋™์œผ๋กœ ์ง€์›๋˜๊ณ , ์ธ์Šคํ„ด์Šค๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์ƒ๊ธฐ์ง€ ์•Š๋„๋ก ํ™•์‹คํ•˜๊ฒŒ ๋ณด์žฅํ•ด์ค€๋‹จ๋‹ค. (by effective java) ๊ทธ๋Ÿผ ์–ด๋””์„œ ์‚ฌ์šฉ๋ ๊นŒ static ์œผ๋กœ ์„ ์–ธํ•ด์„œ ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ถ€๋ถ„์ด๋‚˜ ํ™˜๊ฒฝ์„ค์ • ๋‚ด์šฉ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ๋„ ๊ทธ ๋ถ€๋ถ„์ด ๋˜‘๊ฐ™์ด ์ ์šฉ๋˜์–ด ์‹คํ–‰๋˜์–ด์•ผ ํ• ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ถ€๋ถ„์„ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๋งŒ๋“ค์–ด ์ƒ์„ฑ๋˜๋Š” ์‹œ๊ฐ„์„ ์ค„์ผ๋•Œ ์Šคํ”„๋ง์—์„œ์˜ DB์ปค๋„ฅ์…˜ ๋กœ์ง

hexo ํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•˜๊ธฐ

๊ฐœ์š” ์ด์ „ํฌ์ŠคํŒ… ์—์„œ ์ด์•ผ๊ธฐ ํ•œ๊ฒƒ๊ณผ ๊ฐ™์ด ์–ด๋Š๊ณณ์—์„œ๋“ ์ง€(์ง‘ ๋˜๋Š” ํšŒ์‚ฌ ๋“ฑ) ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ…์„ ํ• ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ๋‹ค. (git์„ ์ด์šฉํ•ด์„œ.) ๊ทธ๋ž˜์„œ git repository ๋ฅผ ๋‘๊ฐœ๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ , ํ•˜๋‚˜๋Š” ์‹ค์ œ ๋ธ”๋กœ๊ทธ์„œ๋ฒ„๋กœ ์ด์šฉํ•˜๊ณ  ํ•˜๋‚˜๋Š” ๋ธ”๋กœ๊ทธ๋ฅผ ํฌ์ŠคํŒ…ํ•˜๋Š” hexo ํ™˜๊ฒฝ์„ ์ €์žฅํ•˜๊ฒŒ ๋œ๋‹ค. ์ง€๊ธˆ๋ถ€ํ„ฐ ์ด์•ผ๊ธฐ ํ•  ๋‚ด์šฉ์€ hexoํ™˜๊ฒฝ์„ git repository ์—์„œ pull ๋ฐ›์•„์„œ ํ™˜๊ฒฝ๊ตฌ์„ฑํ•˜๋Š” ๋ถ€๋ถ„์„ ์ด์•ผ๊ธฐ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ํ™˜๊ฒฝ๊ตฌ์„ฑ hexo์„ค์น˜์™€ git์„ค์น˜๋Š” ๋˜์–ด์žˆ๋‹ค๊ณ  ๊ฐ€์ •. ๋จผ์ € ๊ตฌ์„ฑํ•  ํด๋”๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด ํด๋”์— hexo ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๊ฒ ๋‹ค๊ณ  ์ดˆ๊ธฐ ์…‹ํŒ…์„ ํ•œ๋‹ค mkdir blog hexo init blog ๊ทธ๋ฆฌ๊ณ  hexoํ™˜๊ฒฝ์„ ์ €์žฅํ•ด๋‘” repository๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋ฏ€๋กœ git์„ค์ •์„ ํ•œ๋‹ค cd blog/ git init git remote add origin https://github.com/taetaetae/hexo.git git fetch ํ•„์š”์—†๋Š”์ดˆ๊ธฐ์…‹ํŒ…์ด ๋˜๋Š” ํŒŒ์ผ์€ ์ง€์šฐ๊ณ  rm source/_posts/hello-world.md rm -r themes/landscape/ #ํ•ด๋‹น ํ…Œ๋งˆ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์ง€์šธํ•„์š”๊ฐ€ ์—†๋‹ค. hexoํ™˜๊ฒฝ repository ๋ฅผ pull๋ฐ›๋Š”๋‹ค git reset --hard origin/master git pull origin master huemanํ…Œ๋งˆ์˜ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฐ€์ •ํ•˜์— ํ•„์š”ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ, ๋‚˜์ค‘์— deploy ํ• ๋•Œ ํ•„์š”ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ด์ค€๋‹ค npm install hexo-deployer-git --save npm install -S hexo-generator-json-content ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ๊ธฐ์กด์ฒ˜๋Ÿผ ํ™˜๊ฒฝ์„ค์ •์ด ๋งˆ๋ฌด๋ฆฌ ๋˜๊ณ , ํฌ์ŠคํŒ…์„ ํ• ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ์ถ”๊ฐ€ canonical ์†์„ฑ npm install –save hexo-auto-canonical ์‚ฌ์ดํŠธ๋งต ์†์„ฑ npm install hexo-generator-seo-friendly-sitemap –save feed ์†์„ฑ npm install hexo-generator-feed –save

hexo + github + blog ์—ฐ๋™ํ•˜๊ธฐ

๋“ค์–ด๊ฐ€๊ธฐ์— ์•ž์„œ ์˜ˆ์ „๋ถ€ํ„ฐ ๋ธ”๋กœ๊ทธ๋ฅผ ์šด์˜ํ•ด์•ผ์ง€ ํ•˜๊ตฌ์„œ tistory, naver blog ๋“ฑ ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์œผ๋กœ ์‹œ์ž‘์„ ํ–ˆ์—ˆ์ง€๋งŒ ์ด๋ ‡๋‹คํ•  ์šด์˜์ด ์•ˆ๋˜์—ˆ๊ณ  ์‚ฌ์‹ค ์—ด์ •์ด ๋ถ€์กฑํ–ˆ์—ˆ๋‹ค. ์ง์ ‘ ํ™ˆํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๋งŽ์€ ํ—ˆ๋“ค์ด ์žˆ๋‹ค๋ณด๋‹ˆ (์„œ๋ฒ„๊ตฌ์ถ•, ํ˜ธ์ŠคํŒ…, ๋„๋ฉ”์ธ ๋“ฑ …) ๊ณ„์† ์ฐจ์ผํ”ผ์ผ ๋ฏธ๋ฃจ๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค github์—์„œ ์ œ๊ณตํ•˜๋Š” pages๋ผ๋Š” ๊ฑธ ์ด์šฉํ•ด์„œ ๋ฌด๋ฃŒ๋กœ ๋„๋ฉ”์ธ๊ณผ ์›นํ˜ธ์ŠคํŒ…์„ ํ• ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ถ€๋ถ„์„ ์•Œ๊ฒŒ๋˜์—ˆ๊ณ , ๊ฑฐ๊ธฐ์—๋‹ค jekyll์„ ์ด์šฉํ•˜๋ฉด ์„ค์น˜ํ˜• ๋ธ”๋กœ๊ทธ๋ฅผ ์šด์˜ํ• ์ˆ˜ ์žˆ๋‹ค๋Š”๊ฒƒ์— ๋†€๋ผ์› ๋‹ค. ํ•˜์ง€๋งŒ jekyll์„ ์ ์šฉํ•ด๋ณด๋ ค๊ณ  ์ด๊ฒƒ์ €๊ฒƒ ํ•˜๋‹ค๋ณด๋‹ˆ ruby๋ผ๋Š” ์–ธ์–ด๋กœ ๋งŒ๋“ค์–ด์ ธ์žˆ๊ณ  ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ์–ด๋ ต๋‹ค๋Š” ๋ถ€๋ถ„์„ ํ™•์ธ, ์ข€๋” ์•Œ์•„๋ณด๋‹ค hexo ๋ผ๋Š” ๊ฑธ๋กœ ํ•ด๋‹น ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜์—ˆ๋‹ค. ํ•„์ž์ฒ˜๋Ÿผ ๋‚จ๋“ค๊ณผ๋Š” ๋‹ค๋ฅธ ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ๊ฑฐ๋‚˜, git command ๊ณต๋ถ€๋„ ํ•˜๋ฉด์„œ ๋ธ”๋กœ๊ทธ๋ฅผ ์šด์˜ํ•ด๋ณผ ์‚ฌ๋žŒ๋“ค์€ ํ•ด๋‹น ๊ธ€์„ ์ฒœ์ฒœํžˆ ๋”ฐ๋ผ์˜ค๋ฉด ์ข‹์„๊ฒƒ ๊ฐ™๋‹ค. hexo ์‹œ์ž‘ํ•˜๊ธฐ hexo ๋ผ๋Š”๊ฑธ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ๋ช‡๊ฐ€์ง€ ์ค€๋น„๋ฌผ์ด ์žˆ๋‹ค. node ์„ค์น˜ git ์„ค์น˜ github์— ๋ธ”๋กœ๊ทธ๋กœ ์‚ฌ์šฉํ•  ๋นˆ repository ์ƒ์„ฑ github์— hexo ์„ค์ •์„ ์ €์žฅํ•  ๋นˆ repository ์ƒ์„ฑ ์œ„ 4๊ฐ€์ง€(?!)๊ฐ€ ์ „๋ถ€ ์„ค์น˜ ๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •์„ ํ•˜๊ณ  ์‹œ์ž‘์„ ํ•ด๋ณด๊ฒ ๋‹ค. hexo ์„ค์น˜ ๊ฐ„๋‹จํ•˜๋‹ค. hexo ํŽ˜์ด์ง€์—๋„ ๋‚˜์™€์žˆ๋Š”๊ฒƒ์ฒ˜๋Ÿผ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. $ npm install -g hexo-cli ๋ธ”๋กœ๊ทธ๋กœ ์šด์˜ํ•  ํด๋” hexo ์ดˆ๊ธฐํ™” ํด๋” ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ž„์˜์˜ ํด๋”๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํด๋”๋ฅผ hexo ๋ช…๋ น์–ด๋กœ ์ดˆ๊ธฐํ™” ์‹œ์ผœ์ค€๋‹ค. $ mkdir <๋””๋ ‰ํ† ๋ฆฌ๋ช…> $ hexo init <๋””๋ ‰ํ† ๋ฆฌ๋ช…> ๋กœ์ปฌ์„œ๋ฒ„ ๋„์›Œ๋ณด๊ธฐ ์ด์ œ ๋กœ์ปฌ์—์„œ ์„œ๋ฒ„๋ฅผ ๋„์›Œ์„œ ๋ธ”๋กœ๊ทธ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋‚˜์˜ค๋Š”์ง€ ํ™•์ธ์„ ํ•ด๋ณด๋ฉด ๋œ๋‹ค. $ hexo s (or server) ๊ฐ„ํ˜น ์„œ๋ฒ„๊ฐ€ ์‹คํ–‰์ด ์•ˆ๋˜๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ, ์ˆ˜์ •ํ•œ ๋ถ€๋ถ„์ด ๋ฐ˜์˜์ด ์•ˆ๋œ๋‹ค๋ฉด clean ๋ช…๋ น์–ด๋ฅผ ํ•œ๋ฒˆ ํ•ด์ค€ ๋‹ค์Œ์— ๋‹ค์‹œ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด์ฃผ๋ฉด ๋˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค. $ hexo clean $ hexo s (or server) http://localhost:4000 ์„ ์ ‘์†ํ•ด์„œ ์ •์ƒ์ ์œผ๋กœ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜์˜ค๋Š”์ง€ ํ™•์ธ์„ ํ•ด๋ณด์ž. ํŽ˜์ด์ง€๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋‚˜์˜จ๋‹ค๋ฉด ์„ฑ๊ณต! ๊ธ€ ์ž‘์„ฑ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด /source/_post/ ์•„๋ž˜์— .md ํŒŒ์ผ์ด ์ƒ์„ฑ์ด ๋œ๋‹ค. $ hexo new <๊ธ€ ์ œ๋ชฉ> ํ•ด๋‹น ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•œ ์—๋””ํ„ฐ๋กœ ์—ด์–ด์„œ ๋งˆํฌ๋‹ค์šด ๋ฌธ๋ฒ•์— ๋งž์ถ”์–ด ์ˆ˜์ •์„ ํ•˜๋ฉด ๋! ์™œ ๋‘๊ฐœ์˜ repository๊ฐ€ ํ•„์š”ํ•œ๊ฐ€ ์•„๋ž˜์—์„œ ์ด์•ผ๊ธฐ ํ•˜๊ฒ ์ง€๋งŒ, ํ•˜๋‚˜๋Š” ์‹ค์ œ ๋ธ”๋กœ๊ทธ ๋‚ด์šฉ์ด ์˜ฌ๋ผ๊ฐˆ ์ €์žฅ์†Œ์ด๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋ธ”๋กœ๊ทธ๋ฅผ ์šด์˜ํ•˜๊ณ  ์žˆ๋Š” hexo ์ž์ฒด๋ฅผ ์ €์žฅํ•  ์ €์žฅ์†Œ์ด๋‹ค. hexo ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์„๊บผ๋ผ๋ฉด(ํ•„์ž์ฒ˜๋Ÿผ ๋‹ค์–‘ํ•œ PC์—์„œ ์—…๋กœ๋“œ ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜์ง€ ์•Š์„๊บผ๋ผ๋ฉด) ํ•˜๋‚˜์˜ ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ๋งŒ ํ•„์š”ํ• ์ˆ˜๋„ ์žˆ๋‹ค. github ์…‹ํŒ… ์ง€๊ธˆ๋ถ€ํ„ฐ๊ฐ€ ์•Œ์งœ๋ฐฐ๊ธฐ๋‹ค. ์ฆ‰ ์ด๊ธ€์„ ํฌ์ŠคํŒ… ํ•˜๋Š” ์˜๋ฏธ. ๋‹ค๋ฅธ ๊ธ€๋“ค์—์„œ๋„ hexo ์‚ฌ์šฉ๋ฒ•์„ ์นœ์ ˆํ•˜๊ฒŒ ์•Œ๋ ค ์ฃผ์…จ์œผ๋‚˜ github์™€์˜ ์—ฐ๋™, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค์‹์œผ๋กœ ์šด์˜ํ•ด์•ผํ• ์ง€๋Š” ์ฐพ๊ธฐ ํž˜๋“ค์—ˆ๋‹ค. ํ•„์ž๋Š” ๊ฐ์œผ๋กœ ๊ทธ๋Ÿฐ๊ฐ€๋ณด๋‹ค(?)ํ•˜๊ณ ์„œ ํ„ฐ๋“ํ•œ ๋ฐ”๋ฅผ ๊ณต์œ ํ•˜๋ คํ•œ๋‹ค. (์ด๊ฒŒ ์ •๋‹ต์€ ์•„๋‹ˆ์ง€๋งŒ, ๋‚˜๋Š” ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ๋งž๊ฒ ๋‹ค ์‹ถ์–ด..) ์ผ๋ฐ˜์ ์œผ๋กœ github์—์„œ ๋ธ”๋กœ๊ทธ๋กœ ์‚ฌ์šฉํ•  repository๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด http://(github์•„์ด๋””).github.io/(repository์ด๋ฆ„) ์œผ๋กœ ๋ธ”๋กœ๊ทธ๊ฐ€ ๋งŒ๋“ค์–ด ์ง€๋Š”๋ฐ ๋ญ”๊ฐ€ ์กฐ๊ธˆ ์ด์ƒํ•ด์„œ ๊ฐ„์ง€๊ฐ€ ์•ˆ๋‚˜์„œ ์ฐพ๊ณ  ์ฐพ์•„์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ํ•„์ž์˜ github ์•„์ด๋””๋Š” taetaetae ์ด๊ณ  ๋„๋ฉ”์ธ์€ ์•„์ด๋”” ๊ทธ๋Œ€๋กœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ http://taetaetae.github.io ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ github์— repository์ด๋ฆ„์„ taetaetae.github.io๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ์—ฌ๊ธฐ๊นŒ์ง€๋งŒ ํ•˜๋ฉด ์ผ๋‹จ github์— ๋ฐฐํฌํ• ์ˆ˜ ์žˆ๋Š” ์ค€๋น„๊ฐ€ ๋˜์–ด์žˆ๋Š” ์ƒํƒœ hexo๋กœ ๋ฐฐํฌํ•˜๊ธฐ ํฌ์ŠคํŒ…ํ•œ ๊ธ€์ด ์ •์ƒ์ ์œผ๋กœ ๋“ฑ๋ก์ด ๋œ ๊ฒƒ์„ ๋กœ์ปฌ์„œ๋ฒ„์—์„œ ํ™•์ธ์ด ๋˜์—ˆ์œผ๋ฉด ์ด ์ƒํƒœ๋ฅผ ์กฐ๊ธˆ์ „ ๋งŒ๋“  github repository์œผ๋กœ ๋ฐฐํฌ(์ •ํ™•ํžˆ ๋งํ•˜๋ฉด git push)ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ๊ทธ์ „์— ์ตœ์ƒ์œ„ ํด๋”์— ์žˆ๋Š” _config.yml ํŒŒ์ผ์„ ์—ด์–ด์„œ github ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ด ์ค˜์•ผ ํ•œ๋‹ค. ํ•˜๋‹จ ์˜์—ญ Deployment ๋ถ€๋ถ„์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•˜๊ณ  ์ €์žฅํ•œ๋‹ค. # Deployment deploy: type: git repo: https://github.com/taetaetae/taetaetae.github.io branch: master ๊ทธ ๋‹ค์Œ hexo ์—์„œ github๋กœ ๋ฐฐํฌํ• ์ˆ˜์žˆ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ด์ค€๋‹ค. $ npm install hexo-deployer-git --save ์ด์ œ ์„ค์ •ํ•œ github์— ๋ฐฐํฌ๋ฅผ ํ•˜๋ฉด ๋! $ hexo deploy 1๋ถ„~3๋ถ„ ๋’ค์— ๋„๋ฉ”์ธ์„ ์ ‘์†ํ•˜์—ฌ ์ •์ƒ์ ์œผ๋กœ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜์˜ค๋Š”์ง€ ํ™•์ธํ•˜๊ณ , github์— ํŒŒ์ผ๋“ค์ด push๊ฐ€ ์ž˜ ๋˜์—ˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•œ๋‹ค. ํ–ฅํ›„ ๊ด€๋ฆฌ hexo ์ •๋ณด ์ €์žฅ ๋‚˜์ค‘์— ๋‹ค๋ฅธ PC์—์„œ๋„ ๋ธ”๋กœ๊ทธ๋ฅผ ํฌ์ŠคํŒ… ํ•  ๊ฒฝ์šฐ๊ฐ€ ์žˆ์œผ๋‹ˆ hexo๋ฅผ ์ด์šฉํ•˜์—ฌ ํฌ์ŠคํŒ… ํ•œ ํ™˜๊ฒฝ ์ž์ฒด๋ฅผ ์ €์žฅ ํ•ด์•ผํ•  ํ•„์š”๊ฐ€ ์ƒ๊ฒผ๋‹ค. ๋”ฐ๋ผ์„œ ๋งŒ๋“ค์—ˆ๋˜ ํด๋” ๋˜ํ•œ github์— ์—…๋กœ๋“œ๋ฅผ ํ•ด๋†“๋Š”๊ฒŒ ์ข‹์„๊ฒƒ ๊ฐ™๋‹ค (์ง€๊ทนํžˆ ๊ฐœ์ธ์ ์ธ ์ƒ๊ฐ) git command ์„ค๋ช…์€ ๋”ฐ๋กœ ์ •๋ฆฌํ•˜์ง€ ์•Š๊ฒ ๋‹ค.

์ฒซ๋ฒˆ์งธ ํฌ์ŠคํŒ…

์‹œ์ž‘์€ ์–ธ์ œ๋“ ์ง€ ์ƒˆ๋กญ๊ณ  ๋–จ๋ฆฌ๊ณ  ๊ฐ€์Šด๋ฒ…์ฐจ๋Š” ์ˆœ๊ฐ„์ด๋‹ค. ๊ณผ์—ฐ ์ด ๋ธ”๋กœ๊ทธ๋ฅผ ์ž˜ ์šด์˜ํ• ์ˆ˜ ์žˆ์„๋Ÿฐ์ง€.. ์ œ๋Œ€๋กœ ํ•œ๋ฒˆ ๊ด€๋ฆฌ ํ•ด๋ณด๊ณ , ๋‚˜๋งŒ์˜ ๊ณต๊ฐ„์œผ๋กœ ๊พธ๋ฉฐ๋ณด์ž!