์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿ” ํŠธ๋žœ์žญ์…˜(Transaction)๊ณผ ACID ํŠน์„ฑ ์™„๋ฒฝ ์ดํ•ดํ•˜๊ธฐ

๐Ÿ” ํŠธ๋žœ์žญ์…˜(Transaction)๊ณผ ACID ํŠน์„ฑ ์™„๋ฒฝ ์ดํ•ดํ•˜๊ธฐ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ•ต์‹ฌ ๊ฐœ๋…์„ ์นœ๊ตฌ์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ํ’€์–ด๋“œ๋ฆฝ๋‹ˆ๋‹ค!

Transaction START Atomicity Consistency Isolation Durability Transaction COMMIT SUCCESS ROLLBACK

๐Ÿ’ฌ ํŠธ๋žœ์žญ์…˜, ๋„๋Œ€์ฒด ๋ญ๊ธธ๋ž˜?

์•ผ, ์นœ๊ตฌ์•ผ! ๐Ÿ˜Š ์˜ค๋Š˜์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ •๋ง์ •๋ง ์ค‘์š”ํ•œ ๊ฐœ๋…์ธ ํŠธ๋žœ์žญ์…˜(Transaction)์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด๋ณผ๊นŒ ํ•ด. ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ณต๋ถ€ํ•˜๋‹ค ๋ณด๋ฉด ์ด ๋‹จ์–ด ์ง„์งœ ๋งŽ์ด ๋“ฃ๊ฒŒ ๋˜๋Š”๋ฐ, ์ฒ˜์Œ์—” ์ข€ ์–ด๋ ต๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์–ด. ํ•˜์ง€๋งŒ ๊ฑฑ์ • ๋งˆ! ๋‚ด๊ฐ€ ์ตœ๋Œ€ํ•œ ์‰ฝ๊ณ  ์žฌ๋ฏธ์žˆ๊ฒŒ ์„ค๋ช…ํ•ด์ค„๊ฒŒ.

ํŠธ๋žœ์žญ์…˜์„ ํ•œ๋งˆ๋””๋กœ ์ •์˜ํ•˜๋ฉด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ์ž‘์—…์˜ ๋…ผ๋ฆฌ์  ๋‹จ์œ„์•ผ. ์Œ... ์ด๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ข€ ์ถ”์ƒ์ ์ด์ง€? ๐Ÿค” ์ข€ ๋” ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด๋ณผ๊ฒŒ.

์€ํ–‰ ATM์—์„œ ๋ˆ์„ ์ด์ฒดํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด. ๋„ˆ์˜ ๊ณ„์ขŒ์—์„œ 10๋งŒ์›์„ ๋นผ๊ณ , ์นœ๊ตฌ ๊ณ„์ขŒ์— 10๋งŒ์›์„ ๋„ฃ๋Š” ๊ฑฐ์ง€. ์ด ๊ณผ์ •์€ ์‚ฌ์‹ค ๋‘ ๊ฐ€์ง€ ์ž‘์—…์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์–ด:

1๋‹จ๊ณ„: ๋‚ด ๊ณ„์ขŒ์—์„œ 10๋งŒ์› ์ฐจ๊ฐ ๐Ÿ’ธ

2๋‹จ๊ณ„: ์นœ๊ตฌ ๊ณ„์ขŒ์— 10๋งŒ์› ์ถ”๊ฐ€ ๐Ÿ’ฐ

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ 1๋‹จ๊ณ„๋Š” ์„ฑ๊ณตํ–ˆ๋Š”๋ฐ, ๊ฐ‘์ž๊ธฐ ์‹œ์Šคํ…œ์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ์„œ 2๋‹จ๊ณ„๊ฐ€ ์‹คํŒจํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ๐Ÿ˜ฑ ๋‚ด ๋ˆ์€ ์‚ฌ๋ผ์กŒ๋Š”๋ฐ ์นœ๊ตฌ๋Š” ๋ชป ๋ฐ›๋Š” ์ตœ์•…์˜ ์ƒํ™ฉ์ด ๋ฒŒ์–ด์ง€๋Š” ๊ฑฐ์ง€! ์ด๋Ÿฐ ์ผ์ด ์ ˆ๋Œ€ ์ผ์–ด๋‚˜๋ฉด ์•ˆ ๋˜์ž–์•„?

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

๐ŸŽฏ ํŠธ๋žœ์žญ์…˜์˜ ํ•ต์‹ฌ ๊ฐœ๋…

ํŠธ๋žœ์žญ์…˜์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋Š” ํ•˜๋‚˜์˜ ๋…ผ๋ฆฌ์  ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์ž‘์—…์˜ ๋‹จ์œ„ ๋˜๋Š” ํ•œ๊บผ๋ฒˆ์— ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•  ์ผ๋ จ์˜ ์—ฐ์‚ฐ๋“ค์„ ์˜๋ฏธํ•ด.

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

๐Ÿ”ค ACID? ์‚ฐ์„ฑ? ์•„๋‹ˆ์•ผ, ํŠธ๋žœ์žญ์…˜์˜ 4๊ฐ€์ง€ ํŠน์„ฑ์ด์•ผ!

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜์˜ ํ•ต์‹ฌ์ธ ACID ํŠน์„ฑ์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ์‹œ๊ฐ„์ด์•ผ! ๐ŸŽ“ ACID๋Š” Atomicity, Consistency, Isolation, Durability์˜ ์•ž๊ธ€์ž๋ฅผ ๋”ด ๊ฑฐ์•ผ. ํ•˜๋‚˜์”ฉ ์ฒœ์ฒœํžˆ ํŒŒํ—ค์ณ๋ณด์ž!

ACID Properties Atomicity All or Nothing โœ“ Complete Success โœ— Consistency Valid State Before After Rules Maintained Isolation Independent T1 T2 No Interference Durability Permanent COMMIT SAVED Forever Stored

โš›๏ธ A - Atomicity (์›์ž์„ฑ)

์ฒซ ๋ฒˆ์งธ ํŠน์„ฑ์€ ์›์ž์„ฑ(Atomicity)์ด์•ผ. ์›์ž(Atom)๋Š” ๋” ์ด์ƒ ์ชผ๊ฐค ์ˆ˜ ์—†๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„๋ผ๋Š” ๋œป์ด์ง€? ํŠธ๋žœ์žญ์…˜์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์•ผ! ๐Ÿ”ฌ

์›์ž์„ฑ์€ ํŠธ๋žœ์žญ์…˜์˜ ๋ชจ๋“  ์—ฐ์‚ฐ์ด ์™„์ „ํžˆ ์ˆ˜ํ–‰๋˜๊ฑฐ๋‚˜, ์•„์˜ˆ ์ˆ˜ํ–‰๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค๋Š” ํŠน์„ฑ์ด์•ผ. ์ด๊ฑธ "All or Nothing" ์›์น™์ด๋ผ๊ณ ๋„ ํ•ด. ์ค‘๊ฐ„ ์ƒํƒœ๋Š” ์กด์žฌํ•  ์ˆ˜ ์—†์–ด!

๐ŸŽฏ ์‹ค์ƒํ™œ ์˜ˆ์‹œ:

์˜จ๋ผ์ธ ์‡ผํ•‘๋ชฐ์—์„œ ์ƒํ’ˆ์„ ๊ตฌ๋งคํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…๋“ค์ด ์ผ์–ด๋‚˜์•ผ ํ•ด:

1๏ธโƒฃ ์žฌ๊ณ ์—์„œ ์ƒํ’ˆ 1๊ฐœ ์ฐจ๊ฐ
2๏ธโƒฃ ์ฃผ๋ฌธ ํ…Œ์ด๋ธ”์— ์ฃผ๋ฌธ ์ •๋ณด ์ถ”๊ฐ€
3๏ธโƒฃ ๊ฒฐ์ œ ํ…Œ์ด๋ธ”์— ๊ฒฐ์ œ ์ •๋ณด ๊ธฐ๋ก
4๏ธโƒฃ ๊ณ ๊ฐ ํฌ์ธํŠธ ์ฐจ๊ฐ

๋งŒ์•ฝ 3๋ฒˆ๊นŒ์ง€๋Š” ์„ฑ๊ณตํ–ˆ๋Š”๋ฐ 4๋ฒˆ์—์„œ ์‹คํŒจํ•˜๋ฉด? ๐Ÿ˜ฐ ์›์ž์„ฑ ๋•๋ถ„์— 1~3๋ฒˆ ์ž‘์—…๋„ ๋ชจ๋‘ ์ทจ์†Œ(Rollback)๋˜์–ด์„œ ์•„๋ฌด ์ผ๋„ ์—†์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋Œ์•„๊ฐ€!

์›์ž์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” Commit๊ณผ Rollback์ด๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์—ฐ์‚ฐ์„ ์ œ๊ณตํ•ด:

์—ฐ์‚ฐ ์„ค๋ช… ๊ฒฐ๊ณผ
Commit ํŠธ๋žœ์žญ์…˜์˜ ๋ชจ๋“  ์ž‘์—…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋จ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ˜์˜ โœ…
Rollback ํŠธ๋žœ์žญ์…˜ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•จ ๋ชจ๋“  ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ทจ์†Œ๋˜๊ณ  ์ด์ „ ์ƒํƒœ๋กœ ๋ณต๊ตฌ โ†ฉ๏ธ
-- SQL ํŠธ๋žœ์žญ์…˜ ์˜ˆ์‹œ
BEGIN TRANSACTION;

UPDATE accounts SET balance = balance - 100000 WHERE user_id = 'user1';
UPDATE accounts SET balance = balance + 100000 WHERE user_id = 'user2';

-- ๋ชจ๋“  ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๋ฉด
COMMIT;

-- ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด
ROLLBACK;

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด, BEGIN TRANSACTION์œผ๋กœ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ๋ชจ๋“  ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๋ฉด COMMIT์œผ๋กœ ํ™•์ •ํ•˜๊ณ , ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด ROLLBACK์œผ๋กœ ๋˜๋Œ๋ฆฌ๋Š” ๊ฑฐ์•ผ. ๊ฐ„๋‹จํ•˜์ง€? ๐Ÿ˜Š

๐ŸŽฏ C - Consistency (์ผ๊ด€์„ฑ)

๋‘ ๋ฒˆ์งธ๋Š” ์ผ๊ด€์„ฑ(Consistency)์ด์•ผ. ์ด๊ฑด ํŠธ๋žœ์žญ์…˜์ด ์‹คํ–‰๋˜๊ธฐ ์ „๊ณผ ํ›„์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ผ๊ด€๋œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค๋Š” ํŠน์„ฑ์ด์•ผ. ๐Ÿ”„

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฌด๊ฒฐ์„ฑ ์ œ์•ฝ์กฐ๊ฑด๋“ค์ด ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค๋ฉด:

๐Ÿ“Œ ๊ธฐ๋ณธํ‚ค(Primary Key)๋Š” ์ค‘๋ณต๋  ์ˆ˜ ์—†๋‹ค

๐Ÿ“Œ ์™ธ๋ž˜ํ‚ค(Foreign Key)๋Š” ์ฐธ์กฐํ•˜๋Š” ํ…Œ์ด๋ธ”์— ์‹ค์ œ๋กœ ์กด์žฌํ•˜๋Š” ๊ฐ’์ด์–ด์•ผ ํ•œ๋‹ค

๐Ÿ“Œ NOT NULL ์ œ์•ฝ์ด ์žˆ๋Š” ์ปฌ๋Ÿผ์€ NULL ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค

๐Ÿ“Œ CHECK ์ œ์•ฝ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค (์˜ˆ: ๋‚˜์ด๋Š” 0๋ณด๋‹ค ์ปค์•ผ ํ•จ)

๐Ÿ“Œ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์„ ์ค€์ˆ˜ํ•ด์•ผ ํ•œ๋‹ค (์˜ˆ: ๊ณ„์ขŒ ์ž”์•ก์€ ์Œ์ˆ˜๊ฐ€ ๋  ์ˆ˜ ์—†์Œ)

์ผ๊ด€์„ฑ์€ ์ด๋Ÿฐ ๋ชจ๋“  ๊ทœ์น™๋“ค์ด ํŠธ๋žœ์žญ์…˜ ์ „ํ›„๋กœ ๊นจ์ง€์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•ด์ค˜. ๋งŒ์•ฝ ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๊ฐ€ ์ด๋Ÿฐ ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•œ๋‹ค๋ฉด, ๊ทธ ํŠธ๋žœ์žญ์…˜์€ ์ž๋™์œผ๋กœ ์ทจ์†Œ๋˜๋Š” ๊ฑฐ์ง€! ๐Ÿšซ

๐Ÿ’ก ์ผ๊ด€์„ฑ ์˜ˆ์‹œ

์€ํ–‰ ์‹œ์Šคํ…œ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณผ๊ฒŒ. ์ „์ฒด ๊ณ„์ขŒ์˜ ์ž”์•ก ํ•ฉ๊ณ„๋Š” ํ•ญ์ƒ ์ผ์ •ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ทœ์น™์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž:

ํŠธ๋žœ์žญ์…˜ ์ „:

โ€ข A ๊ณ„์ขŒ: 500,000์›

โ€ข B ๊ณ„์ขŒ: 300,000์›

โ€ข ์ „์ฒด ํ•ฉ๊ณ„: 800,000์› ๐Ÿ’ฐ


ํŠธ๋žœ์žญ์…˜ (A โ†’ B๋กœ 100,000์› ์ด์ฒด):

โ€ข A ๊ณ„์ขŒ: 500,000 - 100,000 = 400,000์›

โ€ข B ๊ณ„์ขŒ: 300,000 + 100,000 = 400,000์›


ํŠธ๋žœ์žญ์…˜ ํ›„:

โ€ข A ๊ณ„์ขŒ: 400,000์›

โ€ข B ๊ณ„์ขŒ: 400,000์›

โ€ข ์ „์ฒด ํ•ฉ๊ณ„: 800,000์› โœ… (์ผ๊ด€์„ฑ ์œ ์ง€!)

๋ณด๋‹ค์‹œํ”ผ ํŠธ๋žœ์žญ์…˜ ์ „ํ›„๋กœ ์ „์ฒด ๊ธˆ์•ก์˜ ํ•ฉ์ด ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜๊ณ  ์žˆ์–ด. ์ด๊ฒŒ ๋ฐ”๋กœ ์ผ๊ด€์„ฑ์ด์•ผ! ๋งŒ์•ฝ ์ค‘๊ฐ„์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ์„œ A ๊ณ„์ขŒ์—์„œ๋งŒ ๋ˆ์ด ๋น ์ง€๊ณ  B ๊ณ„์ขŒ์—๋Š” ์ถ”๊ฐ€๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์ „์ฒด ํ•ฉ๊ณ„๊ฐ€ 700,000์›์ด ๋˜์–ด๋ฒ„๋ ค์„œ ์ผ๊ด€์„ฑ์ด ๊นจ์ง€๋Š” ๊ฑฐ์ง€. ์ด๋Ÿฐ ์ƒํ™ฉ์€ ์ ˆ๋Œ€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์•„! ๐Ÿ›ก๏ธ

๐Ÿ”’ I - Isolation (๊ฒฉ๋ฆฌ์„ฑ)

์„ธ ๋ฒˆ์งธ๋Š” ๊ฒฉ๋ฆฌ์„ฑ(Isolation)์ด์•ผ. ์ด๊ฑด ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ์— ์‹คํ–‰๋  ๋•Œ, ๊ฐ ํŠธ๋žœ์žญ์…˜์ด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ  ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ํŠน์„ฑ์ด์•ผ. ๐Ÿ๏ธ

์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œ์Šคํ…œ์—์„œ๋Š” ์ˆ˜๋งŽ์€ ์‚ฌ์šฉ์ž๋“ค์ด ๋™์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๊ณ  ์žˆ์–ด. ๋งŒ์•ฝ ๊ฒฉ๋ฆฌ์„ฑ์ด ๋ณด์žฅ๋˜์ง€ ์•Š์œผ๋ฉด ์–ด๋–ค ์ผ์ด ๋ฒŒ์–ด์งˆ๊นŒ? ๐Ÿ˜ฑ

๐Ÿšจ ๊ฒฉ๋ฆฌ์„ฑ์ด ์—†๋‹ค๋ฉด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋“ค:

1. Dirty Read (๋”ํ‹ฐ ๋ฆฌ๋“œ) ๐Ÿ’ฉ
ํ•œ ํŠธ๋žœ์žญ์…˜์ด ์•„์ง ์ปค๋ฐ‹ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์ฝ์–ด๋ฒ„๋ฆฌ๋Š” ํ˜„์ƒ

2. Non-Repeatable Read (๋ฐ˜๋ณต ๋ถˆ๊ฐ€๋Šฅํ•œ ์ฝ๊ธฐ) ๐Ÿ”„
ํ•œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‘ ๋ฒˆ ์ฝ์—ˆ๋Š”๋ฐ ๊ฐ’์ด ๋‹ฌ๋ผ์ง€๋Š” ํ˜„์ƒ

3. Phantom Read (ํŒฌํ…€ ๋ฆฌ๋“œ) ๐Ÿ‘ป
ํ•œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ๋‘ ๋ฒˆ ์‹คํ–‰ํ–ˆ๋Š”๋ฐ ๊ฒฐ๊ณผ ํ–‰์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š” ํ˜„์ƒ

์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€(Isolation Level)์ด๋ผ๋Š” ๊ฐœ๋…์„ ์ œ๊ณตํ•ด. ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์€ 4๋‹จ๊ณ„๋กœ ๋‚˜๋‰˜์–ด์ ธ ์žˆ์–ด:

๊ฒฉ๋ฆฌ ์ˆ˜์ค€ Dirty Read Non-Repeatable Read Phantom Read ์„ฑ๋Šฅ
READ UNCOMMITTED ๋ฐœ์ƒ โŒ ๋ฐœ์ƒ โŒ ๋ฐœ์ƒ โŒ ๊ฐ€์žฅ ๋น ๋ฆ„ ๐Ÿš€
READ COMMITTED ๋ฐฉ์ง€ โœ… ๋ฐœ์ƒ โŒ ๋ฐœ์ƒ โŒ ๋น ๋ฆ„ โšก
REPEATABLE READ ๋ฐฉ์ง€ โœ… ๋ฐฉ์ง€ โœ… ๋ฐœ์ƒ โŒ ๋ณดํ†ต โš–๏ธ
SERIALIZABLE ๋ฐฉ์ง€ โœ… ๋ฐฉ์ง€ โœ… ๋ฐฉ์ง€ โœ… ๊ฐ€์žฅ ๋А๋ฆผ ๐Ÿข

๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ๋†’์„์ˆ˜๋ก ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์€ ์ข‹์•„์ง€์ง€๋งŒ ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์€ ๋–จ์–ด์ ธ. ๋ฐ˜๋Œ€๋กœ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ๋‚ฎ์œผ๋ฉด ์„ฑ๋Šฅ์€ ์ข‹์ง€๋งŒ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด. ๊ทธ๋ž˜์„œ ์ƒํ™ฉ์— ๋งž๋Š” ์ ์ ˆํ•œ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ์„ ํƒํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ด! โš–๏ธ

๐ŸŽญ ๊ฒฉ๋ฆฌ์„ฑ ์‹ค์ „ ์˜ˆ์‹œ

์ข€ ๋” ๊ตฌ์ฒด์ ์ธ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ. ๋‘ ๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ์ƒํ’ˆ์˜ ์žฌ๊ณ ๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ตฌ๋งคํ•˜๋ ค๊ณ  ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž:

-- ํŠธ๋žœ์žญ์…˜ 1 (์‚ฌ์šฉ์ž A)
BEGIN TRANSACTION;
SELECT stock FROM products WHERE id = 100;  -- ์žฌ๊ณ : 1๊ฐœ
-- (๊ตฌ๋งค ๊ฒฐ์ • ์ค‘...)
UPDATE products SET stock = stock - 1 WHERE id = 100;
COMMIT;

-- ํŠธ๋žœ์žญ์…˜ 2 (์‚ฌ์šฉ์ž B) - ๋™์‹œ์— ์‹คํ–‰
BEGIN TRANSACTION;
SELECT stock FROM products WHERE id = 100;  -- ์žฌ๊ณ : 1๊ฐœ?
-- (๊ตฌ๋งค ๊ฒฐ์ • ์ค‘...)
UPDATE products SET stock = stock - 1 WHERE id = 100;
COMMIT;

๋งŒ์•ฝ ๊ฒฉ๋ฆฌ์„ฑ์ด ์ œ๋Œ€๋กœ ๋ณด์žฅ๋˜์ง€ ์•Š์œผ๋ฉด, ๋‘ ์‚ฌ์šฉ์ž ๋ชจ๋‘ ์žฌ๊ณ ๊ฐ€ 1๊ฐœ๋ผ๊ณ  ๋ณด๊ณ  ๊ตฌ๋งค๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด. ๊ทธ๋Ÿฌ๋ฉด ์žฌ๊ณ ๊ฐ€ -1๊ฐœ๊ฐ€ ๋˜๋Š” ๋ง๋„ ์•ˆ ๋˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฑฐ์ง€! ๐Ÿ˜จ

ํ•˜์ง€๋งŒ ์ ์ ˆํ•œ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ์„ค์ •๋˜์–ด ์žˆ๋‹ค๋ฉด, ํ•œ ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์€ ๋Œ€๊ธฐํ•˜๊ฑฐ๋‚˜, ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด์„œ ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด! ๐ŸŽฏ

๐Ÿ’พ D - Durability (์ง€์†์„ฑ)

๋งˆ์ง€๋ง‰์€ ์ง€์†์„ฑ(Durability)์ด์•ผ. ์ด๊ฑด ํŠธ๋žœ์žญ์…˜์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ(Commit)๋˜๋ฉด, ๊ทธ ๊ฒฐ๊ณผ๋Š” ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ํŠน์„ฑ์ด์•ผ. ๐Ÿ’ช

์‰ฝ๊ฒŒ ๋งํ•ด์„œ, ํ•œ๋ฒˆ ์ปค๋ฐ‹๋œ ๋ฐ์ดํ„ฐ๋Š” ์‹œ์Šคํ…œ์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์ ˆ๋Œ€ ์‚ฌ๋ผ์ง€๋ฉด ์•ˆ ๋œ๋‹ค๋Š” ๊ฑฐ์•ผ! ์ •์ „์ด ๋‚˜๋“ , ์„œ๋ฒ„๊ฐ€ ๋‹ค์šด๋˜๋“ , ํ•˜๋“œ๋””์Šคํฌ๊ฐ€ ๊ณ ์žฅ๋‚˜๋“  ์ƒ๊ด€์—†์ด ๋ง์ด์•ผ. ๐Ÿ”ฅ

๐Ÿ›ก๏ธ ์ง€์†์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•๋“ค:

1. ๋กœ๊ทธ ๊ธฐ๋ฐ˜ ๋ณต๊ตฌ (Log-based Recovery) ๐Ÿ“
๋ชจ๋“  ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๋กœ๊ทธ ํŒŒ์ผ์— ๊ธฐ๋กํ•ด๋‘์—ˆ๋‹ค๊ฐ€, ์žฅ์•  ๋ฐœ์ƒ ์‹œ ๋กœ๊ทธ๋ฅผ ์ด์šฉํ•ด ๋ณต๊ตฌ

2. ์ฒดํฌํฌ์ธํŠธ (Checkpoint) โœ”๏ธ
์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋””์Šคํฌ์— ์ €์žฅํ•˜์—ฌ ๋ณต๊ตฌ ์‹œ๊ฐ„ ๋‹จ์ถ•

3. ๋ฐฑ์—…๊ณผ ๋ณต๊ตฌ (Backup & Recovery) ๐Ÿ’ฟ
์ •๊ธฐ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ „์ฒด๋ฅผ ๋ฐฑ์—…ํ•˜์—ฌ ๋Œ€๊ทœ๋ชจ ์žฅ์• ์— ๋Œ€๋น„

4. ๋ณต์ œ (Replication) ๐Ÿ”„
์—ฌ๋Ÿฌ ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์ œํ•˜์—ฌ ํ•œ ์„œ๋ฒ„๊ฐ€ ์ฃฝ์–ด๋„ ๋‹ค๋ฅธ ์„œ๋ฒ„์—์„œ ์„œ๋น„์Šค ๊ณ„์†

ํŠนํžˆ WAL(Write-Ahead Logging)์ด๋ผ๋Š” ๊ธฐ๋ฒ•์ด ๋งŽ์ด ์‚ฌ์šฉ๋ผ. ์ด๊ฑด ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์ œ๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ ์ „์— ๋จผ์ € ๋กœ๊ทธ์— ๊ธฐ๋กํ•˜๋Š” ๋ฐฉ์‹์ด์•ผ. ๊ทธ๋ž˜์„œ ๋งŒ์•ฝ ์‹œ์Šคํ…œ์ด ๊ฐ‘์ž๊ธฐ ์ฃฝ๋”๋ผ๋„, ์žฌ์‹œ์ž‘ํ•  ๋•Œ ๋กœ๊ทธ๋ฅผ ๋ณด๊ณ  ์–ด๋””๊นŒ์ง€ ์ฒ˜๋ฆฌํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๊ณ , ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ํŠธ๋žœ์žญ์…˜์€ ๋กค๋ฐฑํ•˜๊ณ  ์™„๋ฃŒ๋œ ํŠธ๋žœ์žญ์…˜์€ ๋‹ค์‹œ ์ ์šฉํ•  ์ˆ˜ ์žˆ์–ด! ๐ŸŽฏ

๐Ÿ” ์ง€์†์„ฑ ์‹ค์ „ ์‹œ๋‚˜๋ฆฌ์˜ค

์‹ค์ œ ์ƒํ™ฉ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ด๋ณด์ž:

์‹œ๋‚˜๋ฆฌ์˜ค: ์˜จ๋ผ์ธ ์‡ผํ•‘๋ชฐ์—์„œ ๊ณ ๊ฐ์ด 100๋งŒ์›์งœ๋ฆฌ ์ƒํ’ˆ์„ ๊ตฌ๋งคํ–ˆ์–ด.

14:30:00 - ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ๐Ÿš€
14:30:01 - ์ฃผ๋ฌธ ์ •๋ณด ์ƒ์„ฑ
14:30:02 - ๊ฒฐ์ œ ์ฒ˜๋ฆฌ
14:30:03 - ์žฌ๊ณ  ์ฐจ๊ฐ
14:30:04 - COMMIT ์™„๋ฃŒ โœ…
14:30:05 - ๐Ÿ’ฅ ๊ฐ‘์ž๊ธฐ ์ •์ „ ๋ฐœ์ƒ!

14:35:00 - ์‹œ์Šคํ…œ ์žฌ์‹œ์ž‘ ๐Ÿ”„
14:35:10 - ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณต๊ตฌ ์‹œ์ž‘
14:35:15 - ๋กœ๊ทธ ๋ถ„์„: 14:30:04์— COMMIT ํ™•์ธ
14:35:20 - ๋ณต๊ตฌ ์™„๋ฃŒ: ์ฃผ๋ฌธ ๋ฐ์ดํ„ฐ ์ •์ƒ ํ™•์ธ โœ…

๋ณด๋‹ค์‹œํ”ผ COMMIT์ด ์™„๋ฃŒ๋œ ํ›„์— ์ •์ „์ด ๋ฐœ์ƒํ–ˆ์ง€๋งŒ, ์‹œ์Šคํ…œ์ด ์žฌ์‹œ์ž‘๋˜๋ฉด์„œ ๋กœ๊ทธ๋ฅผ ๋ถ„์„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ๋ณต๊ตฌํ–ˆ์–ด! ์ด๊ฒŒ ๋ฐ”๋กœ ์ง€์†์„ฑ์ด์•ผ. ๊ณ ๊ฐ์˜ 100๋งŒ์›์งœ๋ฆฌ ์ฃผ๋ฌธ์ด ์‚ฌ๋ผ์ง€์ง€ ์•Š๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด์กด๋œ ๊ฑฐ์ง€! ๐Ÿ’ฐโœจ

๐ŸŽฌ ํŠธ๋žœ์žญ์…˜์˜ ์ƒ๋ช…์ฃผ๊ธฐ

์ž, ์ด์ œ ํŠธ๋žœ์žญ์…˜์ด ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ๊ทธ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์‚ดํŽด๋ณผ๊นŒ? ํŠธ๋žœ์žญ์…˜์€ ๋งˆ์น˜ ์‚ฌ๋žŒ์˜ ์ธ์ƒ์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ๊ฐ€๋ฉฐ ์ง„ํ–‰๋ผ. ๐ŸŒฑโžก๏ธ๐ŸŒณ

Transaction Lifecycle Active ์‹คํ–‰ ์ค‘ Partially Committed Success Committed ์™„๋ฃŒ โœ“ Failure Failed ์‹คํŒจ โœ— Aborted ์ทจ์†Œ๋จ Rollback ์ƒํƒœ ์„ค๋ช… Active: ํŠธ๋žœ์žญ์…˜์ด ์‹คํ–‰ ์ค‘์ธ ์ƒํƒœ Partially Committed: ๋งˆ์ง€๋ง‰ ์—ฐ์‚ฐ๊นŒ์ง€ ์‹คํ–‰ํ–ˆ์ง€๋งŒ ์•„์ง ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ์ƒํƒœ Committed: ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ์ƒํƒœ Failed / Aborted: ์‹คํŒจํ•˜์—ฌ ๋กค๋ฐฑ๋œ ์ƒํƒœ

๐Ÿ“ ํŠธ๋žœ์žญ์…˜ ์ƒํƒœ ์ƒ์„ธ ์„ค๋ช…

1. Active (ํ™œ์„ฑ ์ƒํƒœ) ๐ŸŸข
ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋˜์–ด ์‹คํ–‰ ์ค‘์ธ ์ƒํƒœ์•ผ. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์ฝ๊ธฐ/์“ฐ๊ธฐ ์—ฐ์‚ฐ๋“ค์ด ์ˆ˜ํ–‰๋˜๊ณ  ์žˆ์–ด. ์ด ์ƒํƒœ์—์„œ๋Š” ์•„์ง ์–ด๋–ค ๋ณ€๊ฒฝ์‚ฌํ•ญ๋„ ํ™•์ •๋˜์ง€ ์•Š์•˜์–ด.

2. Partially Committed (๋ถ€๋ถ„ ์™„๋ฃŒ ์ƒํƒœ) ๐ŸŸก
ํŠธ๋žœ์žญ์…˜์˜ ๋งˆ์ง€๋ง‰ ์—ฐ์‚ฐ๊นŒ์ง€ ๋ชจ๋‘ ์‹คํ–‰ํ–ˆ์ง€๋งŒ, ์•„์ง ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š์€ ์ƒํƒœ์•ผ. ์ด ์‹œ์ ์—์„œ๋Š” ๋ณ€๊ฒฝ์‚ฌํ•ญ๋“ค์ด ๋ฉ”๋ชจ๋ฆฌ(๋ฒ„ํผ)์—๋งŒ ์กด์žฌํ•˜๊ณ  ์žˆ์–ด.

3. Committed (์™„๋ฃŒ ์ƒํƒœ) โœ…
ํŠธ๋žœ์žญ์…˜์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์–ด ๋ชจ๋“  ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅ๋œ ์ƒํƒœ์•ผ. ์ด์ œ ์ด ๋ณ€๊ฒฝ์‚ฌํ•ญ๋“ค์€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ๋„ ๋ณผ ์ˆ˜ ์žˆ์–ด.

4. Failed (์‹คํŒจ ์ƒํƒœ) โŒ
ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰ ์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋” ์ด์ƒ ์ •์ƒ์ ์œผ๋กœ ์ง„ํ–‰ํ•  ์ˆ˜ ์—†๋Š” ์ƒํƒœ์•ผ. ์ด ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ์ž๋™์œผ๋กœ Aborted ์ƒํƒœ๋กœ ์ „ํ™˜๋ผ.

5. Aborted (์ฒ ํšŒ ์ƒํƒœ) ๐Ÿ”™
ํŠธ๋žœ์žญ์…˜์ด ์ทจ์†Œ๋˜์–ด ๋ชจ๋“  ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ๋กค๋ฐฑ๋œ ์ƒํƒœ์•ผ. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์ „์˜ ์ƒํƒœ๋กœ ์™„์ „ํžˆ ๋ณต๊ตฌ๋ผ.

โš™๏ธ ํŠธ๋žœ์žญ์…˜ ์ œ์–ด ๋ช…๋ น์–ด (TCL)

ํŠธ๋žœ์žญ์…˜์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•œ SQL ๋ช…๋ น์–ด๋“ค์„ TCL(Transaction Control Language)์ด๋ผ๊ณ  ํ•ด. ์ฃผ์š” ๋ช…๋ น์–ด๋“ค์„ ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณด์ž! ๐ŸŽฎ

๐ŸŽฏ ์ฃผ์š” TCL ๋ช…๋ น์–ด

BEGIN / START TRANSACTION - ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘
COMMIT - ํŠธ๋žœ์žญ์…˜ ํ™•์ •
ROLLBACK - ํŠธ๋žœ์žญ์…˜ ์ทจ์†Œ
SAVEPOINT - ์ €์žฅ์  ์„ค์ •
SET TRANSACTION - ํŠธ๋žœ์žญ์…˜ ์†์„ฑ ์„ค์ •

๐Ÿš€ BEGIN / START TRANSACTION

ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๋Š” ๋ช…๋ น์–ด์•ผ. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œ์Šคํ…œ์— ๋”ฐ๋ผ BEGIN ๋˜๋Š” START TRANSACTION์„ ์‚ฌ์šฉํ•ด.

-- MySQL, PostgreSQL
START TRANSACTION;

-- SQL Server
BEGIN TRANSACTION;

-- Oracle (์•”๋ฌต์ ์œผ๋กœ ์‹œ์ž‘๋˜๋ฏ€๋กœ ๋ช…์‹œ์  ์„ ์–ธ ๋ถˆํ•„์š”)
-- ํ•˜์ง€๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ์‹œ์ž‘ํ•˜๋ ค๋ฉด
SET TRANSACTION;

โœ… COMMIT

ํŠธ๋žœ์žญ์…˜์˜ ๋ชจ๋“  ์ž‘์—…์„ ํ™•์ •ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ˜์˜ํ•˜๋Š” ๋ช…๋ น์–ด์•ผ. COMMIT์„ ์‹คํ–‰ํ•˜๋ฉด ๋” ์ด์ƒ ๋กค๋ฐฑํ•  ์ˆ˜ ์—†์–ด!

BEGIN TRANSACTION;

INSERT INTO orders (user_id, product_id, quantity, price)
VALUES (1001, 2001, 2, 50000);

UPDATE products 
SET stock = stock - 2 
WHERE product_id = 2001;

UPDATE users 
SET points = points - 50000 
WHERE user_id = 1001;

-- ๋ชจ๋“  ์ž‘์—…์ด ์„ฑ๊ณตํ–ˆ์œผ๋ฏ€๋กœ ํ™•์ •
COMMIT;

โ†ฉ๏ธ ROLLBACK

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

BEGIN TRANSACTION;

UPDATE accounts SET balance = balance - 1000000 WHERE account_id = 'A001';

-- ์ž”์•ก ํ™•์ธ
IF (SELECT balance FROM accounts WHERE account_id = 'A001') < 0 THEN
    -- ์ž”์•ก์ด ๋ถ€์กฑํ•˜๋ฉด ๋กค๋ฐฑ
    ROLLBACK;
    PRINT '์ž”์•ก์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.';
ELSE
    UPDATE accounts SET balance = balance + 1000000 WHERE account_id = 'B001';
    COMMIT;
END IF;

๐Ÿ“ SAVEPOINT

ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์ค‘๊ฐ„ ์ €์žฅ์ ์„ ๋งŒ๋“œ๋Š” ๋ช…๋ น์–ด์•ผ. ์ „์ฒด๋ฅผ ๋กค๋ฐฑํ•˜์ง€ ์•Š๊ณ  ํŠน์ • ์ง€์ ๊นŒ์ง€๋งŒ ๋กค๋ฐฑํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ •๋ง ์œ ์šฉํ•ด! ๐ŸŽฏ

BEGIN TRANSACTION;

-- ์ฒซ ๋ฒˆ์งธ ์ž‘์—…
INSERT INTO orders (order_id, user_id, total) VALUES (1, 100, 50000);
SAVEPOINT sp1;

-- ๋‘ ๋ฒˆ์งธ ์ž‘์—…
UPDATE inventory SET stock = stock - 1 WHERE product_id = 200;
SAVEPOINT sp2;

-- ์„ธ ๋ฒˆ์งธ ์ž‘์—…
INSERT INTO payments (order_id, amount) VALUES (1, 50000);
SAVEPOINT sp3;

-- ์„ธ ๋ฒˆ์งธ ์ž‘์—…์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด sp2๊นŒ์ง€๋งŒ ๋กค๋ฐฑ
ROLLBACK TO sp2;

-- ๋‚˜๋จธ์ง€๋Š” ์œ ์ง€ํ•˜๊ณ  ์ปค๋ฐ‹
COMMIT;

SAVEPOINT๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ ํŠธ๋žœ์žญ์…˜์—์„œ ๋ถ€๋ถ„์ ์ธ ๋กค๋ฐฑ์ด ๊ฐ€๋Šฅํ•ด์ ธ์„œ ํ›จ์”ฌ ์œ ์—ฐํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด! ๐Ÿ˜Š

๐Ÿ” ๋™์‹œ์„ฑ ์ œ์–ด (Concurrency Control)

์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ™˜๊ฒฝ์—์„œ๋Š” ์ˆ˜๋งŽ์€ ํŠธ๋žœ์žญ์…˜๋“ค์ด ๋™์‹œ์— ์‹คํ–‰๋ผ. ์ด๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋“ค์„ ๋ฐฉ์ง€ํ•˜๊ณ  ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ฒ•์ด ๋ฐ”๋กœ ๋™์‹œ์„ฑ ์ œ์–ด์•ผ! ๐Ÿšฆ

๐Ÿ”’ Lock (์ž ๊ธˆ) ๊ธฐ๋ฒ•

Lock์€ ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ์— ๊ฐ™์€ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ์ œ์–ดํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์ด์•ผ. ๋งˆ์น˜ ํ™”์žฅ์‹ค ๋ฌธ์„ ์ž ๊ทธ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ํ•œ ํŠธ๋žœ์žญ์…˜์ด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ์ ‘๊ทผ์„ ์ œํ•œํ•˜๋Š” ๊ฑฐ์ง€! ๐Ÿšช๐Ÿ”

Lock ์ข…๋ฅ˜ ์„ค๋ช… ํŠน์ง•
Shared Lock (S-Lock) ๊ณต์œ  ์ž ๊ธˆ, ์ฝ๊ธฐ ์ž ๊ธˆ ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ์— ์ฝ๊ธฐ ๊ฐ€๋Šฅ ๐Ÿ“–
์“ฐ๊ธฐ๋Š” ๋ถˆ๊ฐ€๋Šฅ โœ๏ธโŒ
Exclusive Lock (X-Lock) ๋ฐฐํƒ€์  ์ž ๊ธˆ, ์“ฐ๊ธฐ ์ž ๊ธˆ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ ๐Ÿ”’
์ฝ๊ธฐ/์“ฐ๊ธฐ ๋ชจ๋‘ ๋…์ 

๐ŸŽญ Lock ํ˜ธํ™˜์„ฑ ๋งคํŠธ๋ฆญ์Šค

ํ˜„์žฌ Lock์ด S-Lock์ผ ๋•Œ:
โ€ข ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ S-Lock ์š”์ฒญ: โœ… ํ—ˆ์šฉ
โ€ข ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ X-Lock ์š”์ฒญ: โŒ ๋Œ€๊ธฐ

ํ˜„์žฌ Lock์ด X-Lock์ผ ๋•Œ:
โ€ข ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ S-Lock ์š”์ฒญ: โŒ ๋Œ€๊ธฐ
โ€ข ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ X-Lock ์š”์ฒญ: โŒ ๋Œ€๊ธฐ

โš ๏ธ Deadlock (๊ต์ฐฉ์ƒํƒœ)

Lock์„ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด Deadlock์ด๋ผ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด. ๋‘ ๊ฐœ ์ด์ƒ์˜ ํŠธ๋žœ์žญ์…˜์ด ์„œ๋กœ๊ฐ€ ๊ฐ€์ง„ Lock์„ ๊ธฐ๋‹ค๋ฆฌ๋ฉด์„œ ๋ฌดํ•œ์ • ๋Œ€๊ธฐํ•˜๋Š” ์ƒํ™ฉ์ด์•ผ. ๐Ÿ˜ฑ

๐Ÿ’€ Deadlock ๋ฐœ์ƒ ์‹œ๋‚˜๋ฆฌ์˜ค

์‹œ๊ฐ„ T1:
โ€ข ํŠธ๋žœ์žญ์…˜ A: ๋ฐ์ดํ„ฐ X์— Lock ํš๋“ ๐Ÿ”’
โ€ข ํŠธ๋žœ์žญ์…˜ B: ๋ฐ์ดํ„ฐ Y์— Lock ํš๋“ ๐Ÿ”’

์‹œ๊ฐ„ T2:
โ€ข ํŠธ๋žœ์žญ์…˜ A: ๋ฐ์ดํ„ฐ Y์— Lock ์š”์ฒญ (๋Œ€๊ธฐ ์ค‘...) โณ
โ€ข ํŠธ๋žœ์žญ์…˜ B: ๋ฐ์ดํ„ฐ X์— Lock ์š”์ฒญ (๋Œ€๊ธฐ ์ค‘...) โณ

๊ฒฐ๊ณผ: ์„œ๋กœ๊ฐ€ ์„œ๋กœ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ต์ฐฉ์ƒํƒœ! ๐Ÿ’ฅ

Deadlock์„ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€์•ผ:

1. Deadlock Prevention (์˜ˆ๋ฐฉ) ๐Ÿ›ก๏ธ
์• ์ดˆ์— Deadlock์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜์ด ๊ฐ™์€ ์ˆœ์„œ๋กœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋„๋ก ๊ฐ•์ œํ•˜๋Š” ๊ฑฐ์•ผ.

2. Deadlock Detection & Recovery (ํƒ์ง€ ๋ฐ ํšŒ๋ณต) ๐Ÿ”
Deadlock์ด ๋ฐœ์ƒํ•˜๋ฉด ๊ฐ์ง€ํ•ด์„œ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์„ ๊ฐ•์ œ๋กœ ๋กค๋ฐฑ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•. ๋Œ€๋ถ€๋ถ„์˜ DBMS๊ฐ€ ์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด.

๐ŸŽฏ 2PL (Two-Phase Locking) ํ”„๋กœํ† ์ฝœ

๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” Lock ํ”„๋กœํ† ์ฝœ์ด์•ผ. ํŠธ๋žœ์žญ์…˜์„ ๋‘ ๋‹จ๊ณ„๋กœ ๋‚˜๋ˆ ์„œ Lock์„ ๊ด€๋ฆฌํ•ด:

Phase 1: Growing Phase (ํ™•์žฅ ๋‹จ๊ณ„) ๐Ÿ“ˆ
โ€ข Lock๋งŒ ํš๋“ํ•  ์ˆ˜ ์žˆ๊ณ , ํ•ด์ œ๋Š” ๋ถˆ๊ฐ€๋Šฅ
โ€ข ํ•„์š”ํ•œ ๋ชจ๋“  Lock์„ ํš๋“ํ•˜๋Š” ๋‹จ๊ณ„

Phase 2: Shrinking Phase (์ถ•์†Œ ๋‹จ๊ณ„) ๐Ÿ“‰
โ€ข Lock๋งŒ ํ•ด์ œํ•  ์ˆ˜ ์žˆ๊ณ , ์ƒˆ๋กœ์šด ํš๋“์€ ๋ถˆ๊ฐ€๋Šฅ
โ€ข ํš๋“ํ•œ Lock๋“ค์„ ์ˆœ์ฐจ์ ์œผ๋กœ ํ•ด์ œํ•˜๋Š” ๋‹จ๊ณ„

2PL์„ ์‚ฌ์šฉํ•˜๋ฉด ์ง๋ ฌ์„ฑ(Serializability)์ด ๋ณด์žฅ๋˜์–ด์„œ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ํŠธ๋žœ์žญ์…˜๋“ค์ด ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋œ ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์–ด! โœจ

๐ŸŽช ์‹ค์ „ ์˜ˆ์ œ: ์˜จ๋ผ์ธ ์‡ผํ•‘๋ชฐ ์‹œ์Šคํ…œ

์ด๋ก ๋งŒ ๋ฐฐ์šฐ๋ฉด ์žฌ๋ฏธ์—†์ง€! ๐Ÿ˜… ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์˜ ๊ฒฐ์ œ ์‹œ์Šคํ…œ์„ ์˜ˆ๋กœ ๋“ค์–ด ๊ตฌ์ฒด์ ์ธ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž!

๐Ÿ’ณ ์‹œ๋‚˜๋ฆฌ์˜ค: ์žฌ๋Šฅ ๊ตฌ๋งค ํ”„๋กœ์„ธ์Šค

์‚ฌ์šฉ์ž๊ฐ€ ์žฌ๋Šฅ๋„ท์—์„œ ์–ด๋–ค ์žฌ๋Šฅ์„ ๊ตฌ๋งคํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…๋“ค์ด ์›์ž์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•ด:

1๏ธโƒฃ ๊ตฌ๋งค์ž์˜ ํฌ์ธํŠธ ์ฐจ๊ฐ
2๏ธโƒฃ ํŒ๋งค์ž์˜ ํฌ์ธํŠธ ์ฆ๊ฐ€
3๏ธโƒฃ ์ฃผ๋ฌธ ์ •๋ณด ์ƒ์„ฑ
4๏ธโƒฃ ์žฌ๋Šฅ ํŒ๋งค ํšŸ์ˆ˜ ์ฆ๊ฐ€
5๏ธโƒฃ ์•Œ๋ฆผ ๋ฐœ์†ก (์„ ํƒ์ )

-- ์žฌ๋Šฅ ๊ตฌ๋งค ํŠธ๋žœ์žญ์…˜
BEGIN TRANSACTION;

DECLARE @buyer_id INT = 1001;
DECLARE @seller_id INT = 2001;
DECLARE @talent_id INT = 5001;
DECLARE @price INT = 50000;
DECLARE @buyer_balance INT;

-- 1. ๊ตฌ๋งค์ž ์ž”์•ก ํ™•์ธ
SELECT @buyer_balance = points 
FROM users 
WHERE user_id = @buyer_id;

-- ์ž”์•ก ๋ถ€์กฑ ์ฒดํฌ
IF @buyer_balance < @price
BEGIN
    ROLLBACK;
    RAISERROR('ํฌ์ธํŠธ๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.', 16, 1);
    RETURN;
END

-- ์ €์žฅ์  ์„ค์ •
SAVEPOINT before_payment;

-- 2. ๊ตฌ๋งค์ž ํฌ์ธํŠธ ์ฐจ๊ฐ
UPDATE users 
SET points = points - @price,
    updated_at = GETDATE()
WHERE user_id = @buyer_id;

-- 3. ํŒ๋งค์ž ํฌ์ธํŠธ ์ฆ๊ฐ€ (์ˆ˜์ˆ˜๋ฃŒ 10% ์ฐจ๊ฐ)
UPDATE users 
SET points = points + (@price * 0.9),
    updated_at = GETDATE()
WHERE user_id = @seller_id;

-- 4. ์ฃผ๋ฌธ ์ •๋ณด ์ƒ์„ฑ
INSERT INTO orders (buyer_id, seller_id, talent_id, amount, status, created_at)
VALUES (@buyer_id, @seller_id, @talent_id, @price, 'COMPLETED', GETDATE());

DECLARE @order_id INT = SCOPE_IDENTITY();

-- 5. ์žฌ๋Šฅ ํŒ๋งค ํšŸ์ˆ˜ ์ฆ๊ฐ€
UPDATE talents 
SET sales_count = sales_count + 1,
    updated_at = GETDATE()
WHERE talent_id = @talent_id;

-- 6. ๊ฑฐ๋ž˜ ๋‚ด์—ญ ๊ธฐ๋ก
INSERT INTO transactions (order_id, type, amount, created_at)
VALUES (@order_id, 'PURCHASE', @price, GETDATE());

-- ๋ชจ๋“  ์ž‘์—… ์„ฑ๊ณต ์‹œ ์ปค๋ฐ‹
COMMIT;

-- ์„ฑ๊ณต ๋ฉ”์‹œ์ง€
PRINT '์žฌ๋Šฅ ๊ตฌ๋งค๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!';
PRINT '์ฃผ๋ฌธ๋ฒˆํ˜ธ: ' + CAST(@order_id AS VARCHAR);

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ์ž‘์—…๋“ค์ด ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์—ฌ์žˆ์–ด. ์ค‘๊ฐ„์— ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ROLLBACK๋˜์–ด์„œ ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„! ๐ŸŽฏ

๐Ÿ”„ ๋™์‹œ ๊ตฌ๋งค ์ฒ˜๋ฆฌ ์˜ˆ์ œ

๊ฐ™์€ ์žฌ๋Šฅ์„ ์—ฌ๋Ÿฌ ๋ช…์ด ๋™์‹œ์— ๊ตฌ๋งคํ•˜๋ ค๊ณ  ํ•  ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ๊นŒ? ๊ฒฉ๋ฆฌ ์ˆ˜์ค€๊ณผ Lock์„ ํ™œ์šฉํ•œ ์˜ˆ์ œ๋ฅผ ๋ณด์ž:

-- ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ์„ค์ •
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

BEGIN TRANSACTION;

DECLARE @talent_id INT = 5001;
DECLARE @available_slots INT;
DECLARE @max_slots INT;

-- ์žฌ๋Šฅ์˜ ๋‚จ์€ ์Šฌ๋กฏ ํ™•์ธ (X-Lock ํš๋“)
SELECT @available_slots = available_slots,
       @max_slots = max_slots
FROM talents WITH (XLOCK, ROWLOCK)
WHERE talent_id = @talent_id;

-- ์Šฌ๋กฏ ํ™•์ธ
IF @available_slots <= 0
BEGIN
    ROLLBACK;
    RAISERROR('์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ์žฌ๋Šฅ์€ ๋งˆ๊ฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.', 16, 1);
    RETURN;
END

-- ์Šฌ๋กฏ ์ฐจ๊ฐ
UPDATE talents 
SET available_slots = available_slots - 1
WHERE talent_id = @talent_id;

-- ๋‚˜๋จธ์ง€ ๊ตฌ๋งค ํ”„๋กœ์„ธ์Šค...
-- (ํฌ์ธํŠธ ์ฐจ๊ฐ, ์ฃผ๋ฌธ ์ƒ์„ฑ ๋“ฑ)

COMMIT;

PRINT '๊ตฌ๋งค๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!';

WITH (XLOCK, ROWLOCK)๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹น ํ–‰์— ๋ฐฐํƒ€์  ์ž ๊ธˆ์„ ๊ฑธ์—ˆ์–ด. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ์— ๊ฐ™์€ ์žฌ๋Šฅ์„ ๊ตฌ๋งคํ•˜๋ ค๊ณ  ํ•ด๋„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์–ด์„œ ์Šฌ๋กฏ์ด ์Œ์ˆ˜๊ฐ€ ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด! ๐Ÿ”’

๐Ÿšจ ํŠธ๋žœ์žญ์…˜ ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ

ํŠธ๋žœ์žญ์…˜์€ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ ๋ฌธ์ œ๋‚˜ ๋ฐ๋“œ๋ฝ์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด. ์‹ค๋ฌด์—์„œ ๊ผญ ์ง€์ผœ์•ผ ํ•  ์ฃผ์˜์‚ฌํ•ญ๋“ค์„ ์•Œ์•„๋ณด์ž! โš ๏ธ

โฑ๏ธ 1. ํŠธ๋žœ์žญ์…˜์€ ๊ฐ€๋Šฅํ•œ ์งง๊ฒŒ ์œ ์ง€ํ•˜๋ผ

โŒ ๋‚˜์œ ์˜ˆ:

BEGIN TRANSACTION;

-- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…
UPDATE accounts SET balance = balance - 10000 WHERE id = 1;

-- ์™ธ๋ถ€ API ํ˜ธ์ถœ (์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆผ!)
EXEC sp_send_email @to='user@example.com', @subject='๊ฒฐ์ œ ์™„๋ฃŒ';

-- ํŒŒ์ผ ์ฒ˜๋ฆฌ (์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆผ!)
EXEC sp_generate_pdf @order_id=12345;

-- ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…
INSERT INTO logs (message) VALUES ('Payment completed');

COMMIT;

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์ด ๋„ˆ๋ฌด ์˜ค๋ž˜ ์œ ์ง€๋˜์–ด์„œ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜๋“ค์ด ๋Œ€๊ธฐํ•˜๊ฒŒ ๋ผ! ๐Ÿ˜ฐ

โœ… ์ข‹์€ ์˜ˆ:

-- ํŠธ๋žœ์žญ์…˜์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…๋งŒ!
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 10000 WHERE id = 1;
INSERT INTO logs (message) VALUES ('Payment completed');
COMMIT;

-- ์™ธ๋ถ€ ์ž‘์—…์€ ํŠธ๋žœ์žญ์…˜ ๋ฐ–์—์„œ
EXEC sp_send_email @to='user@example.com', @subject='๊ฒฐ์ œ ์™„๋ฃŒ';
EXEC sp_generate_pdf @order_id=12345;

ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ๋Š” ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…๋งŒ ์ˆ˜ํ–‰ํ•˜๊ณ , ์™ธ๋ถ€ API ํ˜ธ์ถœ์ด๋‚˜ ํŒŒ์ผ ์ฒ˜๋ฆฌ๋Š” ํŠธ๋žœ์žญ์…˜ ๋ฐ–์—์„œ ์ฒ˜๋ฆฌํ•ด! ๐ŸŽฏ

๐ŸŽฏ 2. ์ ์ ˆํ•œ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ์„ ํƒํ•˜๋ผ

๋ฌด์กฐ๊ฑด ๋†’์€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ์ข‹์€ ๊ฒŒ ์•„๋‹ˆ์•ผ. ์ƒํ™ฉ์— ๋งž๋Š” ์ ์ ˆํ•œ ์ˆ˜์ค€์„ ์„ ํƒํ•ด์•ผ ํ•ด:

์ƒํ™ฉ ๊ถŒ์žฅ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ์ด์œ 
๋‹จ์ˆœ ์กฐํšŒ READ COMMITTED ์„ฑ๋Šฅ๊ณผ ์ผ๊ด€์„ฑ์˜ ๊ท ํ˜• โš–๏ธ
ํ†ต๊ณ„ ๋ฆฌํฌํŠธ READ UNCOMMITTED ์ •ํ™•๋„๋ณด๋‹ค ์†๋„ ์šฐ์„  ๐Ÿš€
๊ธˆ์œต ๊ฑฐ๋ž˜ SERIALIZABLE ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ์ตœ์šฐ์„  ๐Ÿ”’
์žฌ๊ณ  ๊ด€๋ฆฌ REPEATABLE READ ์ผ๊ด€๋œ ์ฝ๊ธฐ ๋ณด์žฅ ๐Ÿ“Š

๐Ÿ”„ 3. ๋ฐ๋“œ๋ฝ์„ ๋ฐฉ์ง€ํ•˜๋ผ

๋ฐ๋“œ๋ฝ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์‹ค์ „ ํŒ๋“ค:

โœ… ํ•ญ์ƒ ๊ฐ™์€ ์ˆœ์„œ๋กœ ํ…Œ์ด๋ธ”์— ์ ‘๊ทผํ•˜๊ธฐ
๋ชจ๋“  ํŠธ๋žœ์žญ์…˜์ด A โ†’ B โ†’ C ์ˆœ์„œ๋กœ ์ ‘๊ทผํ•˜๋ฉด ๋ฐ๋“œ๋ฝ ๋ฐœ์ƒ ํ™•๋ฅ ์ด ํฌ๊ฒŒ ์ค„์–ด๋“ค์–ด!

โœ… ์ธ๋ฑ์Šค๋ฅผ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•˜๊ธฐ
์ธ๋ฑ์Šค๊ฐ€ ์—†์œผ๋ฉด ํ…Œ์ด๋ธ” ์ „์ฒด์— Lock์ด ๊ฑธ๋ ค์„œ ๋ฐ๋“œ๋ฝ ์œ„ํ—˜์ด ๋†’์•„์ ธ.

โœ… ํŠธ๋žœ์žญ์…˜ ํฌ๊ธฐ๋ฅผ ์ž‘๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ
ํŠธ๋žœ์žญ์…˜์ด ์งง์„์ˆ˜๋ก Lock ์œ ์ง€ ์‹œ๊ฐ„์ด ์งง์•„์ ธ์„œ ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ์ด ์ค„์–ด๋“ค์–ด.

โœ… ํƒ€์ž„์•„์›ƒ ์„ค์ •ํ•˜๊ธฐ
๋ฌดํ•œ์ • ๋Œ€๊ธฐํ•˜์ง€ ์•Š๋„๋ก ์ ์ ˆํ•œ ํƒ€์ž„์•„์›ƒ์„ ์„ค์ •ํ•ด.

๐Ÿ’พ 4. ๋กค๋ฐฑ ๊ฐ€๋Šฅ์„ฑ์„ ํ•ญ์ƒ ๊ณ ๋ คํ•˜๋ผ

ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ํ•ญ์ƒ ์—ผ๋‘์— ๋‘๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ด:

BEGIN TRY
    BEGIN TRANSACTION;
    
    -- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…๋“ค
    UPDATE inventory SET stock = stock - 1 WHERE product_id = 100;
    INSERT INTO orders (product_id, quantity) VALUES (100, 1);
    
    COMMIT;
    
    -- ์ปค๋ฐ‹ ์„ฑ๊ณต ํ›„์—๋งŒ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์ž‘์—…
    EXEC sp_send_confirmation_email;
    
END TRY
BEGIN CATCH
    -- ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ๋กค๋ฐฑ
    IF @@TRANCOUNT > 0
        ROLLBACK;
    
    -- ์˜ค๋ฅ˜ ๋กœ๊น…
    INSERT INTO error_logs (error_message, error_time)
    VALUES (ERROR_MESSAGE(), GETDATE());
    
    -- ์˜ค๋ฅ˜ ์žฌ๋ฐœ์ƒ
    THROW;
END CATCH;

๐Ÿ“Š 5. ํŠธ๋žœ์žญ์…˜ ๋กœ๊ทธ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋ผ

ํŠธ๋žœ์žญ์…˜ ๋กœ๊ทธ๊ฐ€ ๋„ˆ๋ฌด ์ปค์ง€๋ฉด ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด. ์ •๊ธฐ์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  ๊ด€๋ฆฌํ•ด์•ผ ํ•ด:

๐Ÿ” ์ฒดํฌํ•ด์•ผ ํ•  ์‚ฌํ•ญ๋“ค:
โ€ข ํŠธ๋žœ์žญ์…˜ ๋กœ๊ทธ ํŒŒ์ผ ํฌ๊ธฐ
โ€ข ์žฅ์‹œ๊ฐ„ ์‹คํ–‰ ์ค‘์ธ ํŠธ๋žœ์žญ์…˜
โ€ข ๋นˆ๋ฒˆํ•œ ๋กค๋ฐฑ ๋ฐœ์ƒ
โ€ข ๋ฐ๋“œ๋ฝ ๋ฐœ์ƒ ๋นˆ๋„
โ€ข Lock ๋Œ€๊ธฐ ์‹œ๊ฐ„

๐ŸŒŸ NoSQL๊ณผ ํŠธ๋žœ์žญ์…˜

์š”์ฆ˜์€ MongoDB, Redis, Cassandra ๊ฐ™์€ NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋„ ๋งŽ์ด ์‚ฌ์šฉ๋˜์ง€? ๐Ÿš€ NoSQL์—์„œ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋ ๊นŒ?

๐Ÿ“ MongoDB์˜ ํŠธ๋žœ์žญ์…˜

MongoDB๋Š” 4.0 ๋ฒ„์ „๋ถ€ํ„ฐ ๋‹ค์ค‘ ๋ฌธ์„œ ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์–ด. ํ•˜์ง€๋งŒ ์ „ํ†ต์ ์ธ RDBMS์™€๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ด:

// MongoDB ํŠธ๋žœ์žญ์…˜ ์˜ˆ์ œ (Node.js)
const session = client.startSession();

try {
  session.startTransaction();
  
  // ๊ณ„์ขŒ A์—์„œ ์ฐจ๊ฐ
  await accountsCollection.updateOne(
    { accountId: 'A001' },
    { $inc: { balance: -1000 } },
    { session }
  );
  
  // ๊ณ„์ขŒ B์— ์ถ”๊ฐ€
  await accountsCollection.updateOne(
    { accountId: 'B001' },
    { $inc: { balance: 1000 } },
    { session }
  );
  
  // ๊ฑฐ๋ž˜ ๋‚ด์—ญ ๊ธฐ๋ก
  await transactionsCollection.insertOne(
    { from: 'A001', to: 'B001', amount: 1000, date: new Date() },
    { session }
  );
  
  await session.commitTransaction();
  console.log('ํŠธ๋žœ์žญ์…˜ ์„ฑ๊ณต! โœ…');
  
} catch (error) {
  await session.abortTransaction();
  console.log('ํŠธ๋žœ์žญ์…˜ ์‹คํŒจ, ๋กค๋ฐฑ๋จ โŒ');
  throw error;
} finally {
  session.endSession();
}

โšก Redis์˜ ํŠธ๋žœ์žญ์…˜

Redis๋Š” MULTI, EXEC, DISCARD ๋ช…๋ น์–ด๋กœ ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•ด. ํ•˜์ง€๋งŒ ACID์˜ I(Isolation)๋Š” ์™„๋ฒฝํ•˜๊ฒŒ ๋ณด์žฅ๋˜์ง€ ์•Š์•„:

// Redis ํŠธ๋žœ์žญ์…˜ ์˜ˆ์ œ
MULTI
SET account:A:balance 9000
SET account:B:balance 11000
LPUSH transactions "A->B:1000"
EXEC

// ๋˜๋Š” ์กฐ๊ฑด๋ถ€ ํŠธ๋žœ์žญ์…˜ (WATCH ์‚ฌ์šฉ)
WATCH account:A:balance
balance = GET account:A:balance
if balance >= 1000:
    MULTI
    DECRBY account:A:balance 1000
    INCRBY account:B:balance 1000
    EXEC
else:
    UNWATCH

๐ŸŽฏ NoSQL ํŠธ๋žœ์žญ์…˜ ์‚ฌ์šฉ ์‹œ ๊ณ ๋ ค์‚ฌํ•ญ

์žฅ์ : โœ…
โ€ข ์ˆ˜ํ‰์  ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚จ
โ€ข ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์— ์œ ๋ฆฌ
โ€ข ์œ ์—ฐํ•œ ์Šคํ‚ค๋งˆ

๋‹จ์ : โš ๏ธ
โ€ข ACID ๋ณด์žฅ์ด ์ œํ•œ์ ์ผ ์ˆ˜ ์žˆ์Œ
โ€ข ๋ณต์žกํ•œ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋ ค์›€
โ€ข ์กฐ์ธ ์—ฐ์‚ฐ์ด ๋น„ํšจ์œจ์ 

๐Ÿ’ก ๊ฒฐ๋ก :
๊ฐ•๋ ฅํ•œ ํŠธ๋žœ์žญ์…˜์ด ํ•„์š”ํ•˜๋ฉด RDBMS๋ฅผ, ํ™•์žฅ์„ฑ๊ณผ ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•˜๋ฉด NoSQL์„ ์„ ํƒํ•˜๋˜, ์ตœ๊ทผ์—๋Š” ๋‘ ๊ฐ€์ง€๋ฅผ ํ˜ผํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ํด๋ฆฌ๊ธ€๋ž ํผ์‹œ์Šคํ„ด์Šค(Polyglot Persistence) ํŒจํ„ด๋„ ๋งŽ์ด ์‚ฌ์šฉ๋ผ!

๐ŸŽ“ ํŠธ๋žœ์žญ์…˜ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ์‹ค๋ฌด์—์„œ ๊ผญ ์ง€์ผœ์•ผ ํ•  ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค๋ฅผ ์ •๋ฆฌํ•ด๋ณผ๊ฒŒ! ๐Ÿ“š

1๏ธโƒฃ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๋ฅผ ์ตœ์†Œํ™”ํ•˜๋ผ

๊ผญ ํ•„์š”ํ•œ ์ž‘์—…๋งŒ ํŠธ๋žœ์žญ์…˜์— ํฌํ•จ์‹œ์ผœ. ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ, ํŒŒ์ผ I/O, ๋ณต์žกํ•œ ๊ณ„์‚ฐ ๋“ฑ์€ ํŠธ๋žœ์žญ์…˜ ๋ฐ–์—์„œ ์ฒ˜๋ฆฌํ•ด!

2๏ธโƒฃ ๋ช…์‹œ์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•˜๋ผ

์ž๋™ ์ปค๋ฐ‹ ๋ชจ๋“œ์— ์˜์กดํ•˜์ง€ ๋ง๊ณ , BEGIN, COMMIT, ROLLBACK์„ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์„œ ์˜๋„๋ฅผ ๋ช…ํ™•ํžˆ ํ•ด!

3๏ธโƒฃ ์ ์ ˆํ•œ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ์„ ํƒํ•˜๋ผ

๋ฌด์กฐ๊ฑด ๋†’์€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ์•„๋‹ˆ๋ผ, ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š” ์ ์ ˆํ•œ ์ˆ˜์ค€์„ ์„ ํƒํ•ด. ์„ฑ๋Šฅ๊ณผ ์ผ๊ด€์„ฑ์˜ ๊ท ํ˜•์„ ๋งž์ถฐ!

4๏ธโƒฃ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์ฒ ์ €ํžˆ ํ•˜๋ผ

๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ์˜ˆ์™ธ ์ƒํ™ฉ์„ ๊ณ ๋ คํ•˜๊ณ , ์ ์ ˆํ•œ ๋กค๋ฐฑ ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•ด. try-catch-finally ํŒจํ„ด์„ ํ™œ์šฉํ•ด!

5๏ธโƒฃ ๋ฐ๋“œ๋ฝ์„ ์˜ˆ๋ฐฉํ•˜๋ผ

์ผ๊ด€๋œ ์ˆœ์„œ๋กœ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•˜๊ณ , ํƒ€์ž„์•„์›ƒ์„ ์„ค์ •ํ•˜๊ณ , ํŠธ๋žœ์žญ์…˜์„ ์งง๊ฒŒ ์œ ์ง€ํ•ด!

6๏ธโƒฃ ๋กœ๊น…๊ณผ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ๊ตฌ์ถ•ํ•˜๋ผ

ํŠธ๋žœ์žญ์…˜์˜ ์‹œ์ž‘, ์ข…๋ฃŒ, ์‹คํŒจ๋ฅผ ๋กœ๊น…ํ•˜๊ณ , ์„ฑ๋Šฅ ์ง€ํ‘œ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด์„œ ๋ฌธ์ œ๋ฅผ ์กฐ๊ธฐ์— ๋ฐœ๊ฒฌํ•ด!

7๏ธโƒฃ ํ…Œ์ŠคํŠธ๋ฅผ ์ฒ ์ €ํžˆ ํ•˜๋ผ

์ •์ƒ ์ผ€์ด์Šค๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋กค๋ฐฑ ์‹œ๋‚˜๋ฆฌ์˜ค, ๋™์‹œ์„ฑ ํ…Œ์ŠคํŠธ, ์žฅ์•  ์ƒํ™ฉ ํ…Œ์ŠคํŠธ๋„ ๊ผญ ์ˆ˜ํ–‰ํ•ด!

8๏ธโƒฃ ๋ฌธ์„œํ™”๋ฅผ ์ž˜ ํ•˜๋ผ

๋ณต์žกํ•œ ํŠธ๋žœ์žญ์…˜ ๋กœ์ง์€ ์ฃผ์„๊ณผ ๋ฌธ์„œ๋กœ ์ž˜ ์„ค๋ช…ํ•ด๋‘์–ด์•ผ ๋‚˜์ค‘์— ์œ ์ง€๋ณด์ˆ˜ํ•  ๋•Œ ๋„์›€์ด ๋ผ!

๐ŸŽฌ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ ํŠธ๋žœ์žญ์…˜๊ณผ ACID ํŠน์„ฑ์— ๋Œ€ํ•ด ๊นŠ์ด ์žˆ๊ฒŒ ์•Œ์•„๋ดค์–ด! ๐ŸŽ‰ ์ฒ˜์Œ์—” ์–ด๋ ต๊ฒŒ ๋А๊ปด์กŒ์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ํ•˜๋‚˜์”ฉ ์ฐจ๊ทผ์ฐจ๊ทผ ์ดํ•ดํ•˜๋‹ค ๋ณด๋ฉด ๊ทธ๋ ‡๊ฒŒ ์–ด๋ ค์šด ๊ฐœ๋…์€ ์•„๋‹ˆ์•ผ.

ํŠธ๋žœ์žญ์…˜์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ•ต์‹ฌ ๊ฐœ๋…์ด๊ณ , ์‹ค๋ฌด์—์„œ ์ •๋ง์ •๋ง ์ค‘์š”ํ•ด. ํŠนํžˆ ๊ธˆ์œต, ์ „์ž์ƒ๊ฑฐ๋ž˜, ์˜ˆ์•ฝ ์‹œ์Šคํ…œ ๊ฐ™์ด ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์ด ์ค‘์š”ํ•œ ์‹œ์Šคํ…œ์—์„œ๋Š” ํ•„์ˆ˜์ ์ด์ง€! ๐Ÿ’ผ

๐ŸŽฏ ํ•ต์‹ฌ ์š”์•ฝ

ํŠธ๋žœ์žญ์…˜: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ์ž‘์—…์˜ ๋…ผ๋ฆฌ์  ๋‹จ์œ„
ACID: Atomicity, Consistency, Isolation, Durability
์›์ž์„ฑ: All or Nothing - ์ „๋ถ€ ์„ฑ๊ณต ๋˜๋Š” ์ „๋ถ€ ์‹คํŒจ
์ผ๊ด€์„ฑ: ํŠธ๋žœ์žญ์…˜ ์ „ํ›„๋กœ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ ์œ ์ง€
๊ฒฉ๋ฆฌ์„ฑ: ๋™์‹œ ์‹คํ–‰๋˜๋Š” ํŠธ๋žœ์žญ์…˜๋“ค์˜ ๋…๋ฆฝ์„ฑ ๋ณด์žฅ
์ง€์†์„ฑ: ์ปค๋ฐ‹๋œ ๋ฐ์ดํ„ฐ๋Š” ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅ

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์ด๋Ÿฐ ๊ฐœ๋…๋“ค์„ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ณ  ์žˆ์œผ๋ฉด, ๋” ์•ˆ์ •์ ์ด๊ณ  ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด. ๊ทธ๋ฆฌ๊ณ  ๋ฉด์ ‘์—์„œ๋„ ์ •๋ง ์ž์ฃผ ๋‚˜์˜ค๋Š” ์งˆ๋ฌธ์ด๋‹ˆ๊นŒ ๊ผญ ์ˆ™์ง€ํ•ด๋‘๊ธธ ๋ฐ”๋ผ! ๐Ÿ˜Š

ํ˜น์‹œ ๋” ๊ถ๊ธˆํ•œ ๊ฒŒ ์žˆ๊ฑฐ๋‚˜, ์‹ค๋ฌด์—์„œ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ จ ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ  ์žˆ๋‹ค๋ฉด, ์žฌ๋Šฅ๋„ท์˜ ์ง€์‹์ธ์˜ ์ˆฒ์ด๋‚˜ ์ „๋ฌธ๊ฐ€๋“ค์—๊ฒŒ ์งˆ๋ฌธํ•ด๋ณด๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์•ผ. ํ•จ๊ป˜ ๋ฐฐ์šฐ๊ณ  ์„ฑ์žฅํ•˜๋Š” ๊ฒŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๋งค๋ ฅ์ด๋‹ˆ๊นŒ! ๐ŸŒฑ

์ž, ์ด์ œ ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋ฉด์„œ ํŠธ๋žœ์žญ์…˜์„ ์ฒดํ—˜ํ•ด๋ด! ์ด๋ก ๋งŒ ์•„๋Š” ๊ฒƒ๋ณด๋‹ค ์ง์ ‘ ํ•ด๋ณด๋Š” ๊ฒŒ ๋ฐฑ๋ฐฐ ๋‚ซ๊ฑฐ๋“ . ํ™”์ดํŒ…! ๐Ÿ’ชโœจ

Happy Coding! ๐Ÿš€ โœ… COMMIT ๐Ÿ”’ ACID ๐Ÿ’พ DURABLE ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์‹ ๋ขฐ์„ฑ์„ ์ง€ํ‚ค๋Š” ํŠธ๋žœ์žญ์…˜! ๐Ÿ›ก๏ธ
๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.