TL;DR
- ACID ๋ค ๊ธ์ ์ค ๋ฑ๊ธ์ด ์๋ ๊ฒ์ I๋ฟ. ๋๋จธ์ง ์ ์ ์ผ๊ณ ๋๋ ๋์์ด ์๋
- ๊ฒฉ๋ฆฌ ์์ค์ ์ด๋ฆ์ด ์๋๋ผ ์ด๋ค ์ด์ ํ์์ด ๋งํ๋์ง๋ก ํ๋จ. DB๋ง๋ค ์ค์ ๋์์ด ๋ค๋ฆ
- Serializable์ ๊ฐ์ง๋ง ์๋. ์ฌ์๋์ ๊ฒฉ๋ฆฌ ์์ค ํต์ผ์ ์ ํ๋ฆฌ์ผ์ด์ ๋ชซ
AI-assisted
1. ํธ๋์ญ์ ์ด ํธ๋ ๋ฌธ์
๊ณ์ข ์ด์ฒด๋ ์ถ๊ธ๊ณผ ์ ๊ธ ๋ ๋ฒ์ ์ฐ๊ธฐ๋ฅผ ๋ฌถ์ด์ผ ํ๋ค.
UPDATE accounts SET balance = balance - 10000 WHERE id = 1; -- ์ถ๊ธ
UPDATE accounts SET balance = balance + 10000 WHERE id = 2; -- ์
๊ธ๋ ๋ฌธ์ฅ ์ฌ์ด์์ ํ๋ก์ธ์ค๊ฐ ์ฃฝ์ผ๋ฉด ๋์ด ์ฌ๋ผ์ง๋ค. ์ถ๊ธ์ ๋ฐ์๋๊ณ ์ ๊ธ์ ์ ๋๋๋ฐ ๋๋๋ฆด ๋ฐฉ๋ฒ์ด ์๋ค.
ํธ๋์ญ์ ์ ์ฌ๋ฌ ๋ฌธ์ฅ์ ํ๋์ ๋จ์๋ก ๋ฌถ์ด ์ ๋ถ ๋ฐ์๋๊ฑฐ๋ ์ ๋ถ ์ทจ์๋๊ฒ ํ๋ ์ฅ์น๋ค. ์ ๋ฐ๋ง ์ ์ฉ๋ ์ค๊ฐ ์ํ๋ฅผ ๋ฐ์์ ๋ณผ ์ ์๊ฒ ๋ง๋ ๋ค.
BEGIN; -- ์ฌ๊ธฐ์ ์ด๋ฆฐ๋ค
UPDATE accounts SET balance = balance - 10000 WHERE id = 1;
UPDATE accounts SET balance = balance + 10000 WHERE id = 2;
COMMIT; -- ์ฌ๊ธฐ์ ํ์ ๋๋ค๊ฒฝ๊ณ๋ฅผ ๋ง๋๋ ๋ฌธ์ฅ์ ์
์ด๋ค. BEGIN์ผ๋ก ์ด๊ณ COMMIT์ผ๋ก ํ์ ํ๊ณ ROLLBACK์ผ๋ก ๋๋๋ฆฐ๋ค.
ํ์ ์ ์ปค๋ฐ๋ฟ์ด๋ค
ROLLBACK์ ์ง์ ์น๋ ๊ฒฝ์ฐ๋ ์คํ๋ ค ๋๋ฌผ๋ค. ์ปค๋ฐํ์ง ์์ ํธ๋์ญ์
์ ์ด๋ค ๊ฒฝ๋ก๋ก ๋๋๋ ๋กค๋ฐฑ๋๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์ธ๋ฅผ ๋์ง๊ณ ๋น ์ ธ๋๊ฐ๋ฉด ์ปค๋ฐ์ ๋๋ฌํ์ง ๋ชปํ๋ฏ๋ก ๋กค๋ฐฑ๋๋ค
- ์ปค๋ฅ์ ์ด ๋๊ธฐ๋ฉด ์๋ฒ๊ฐ ๊ทธ ์ธ์ ์ ์ด๋ฆฐ ํธ๋์ญ์ ์ ๋กค๋ฐฑํ๋ค
- ์๋ฒ๊ฐ ์ฃฝ์ผ๋ฉด ์ฌ์์ํ ๋ WAL์ ๋ณด๊ณ ์ปค๋ฐ ์ ๋ ๊ฒ์ ๋๋๋ฆฐ๋ค
๊ทธ๋์ ๊ธฐ๋ณธ ์ํ๋ โ์ทจ์โ์ด๊ณ ์ปค๋ฐ๋ง์ด ํ์ ์ด๋ค. ๊ฒฝ๊ณ ์ค๊ณ์ ์ฌ์๋๋ ์ด ์ฑ์ง์ ์ ์ ๋ก ํ๋ค.
์ฃผ์: ๋กค๋ฐฑ์ DB ์๊น์ง๋ง ๋๋๋ฆฐ๋ค
- ์ธ๋ถ API ํธ์ถ, ํ ๋ฐํ, ๋ฉ์ผ ๋ฐ์ก, ํ์ผ ์ฐ๊ธฐ๋ ๋กค๋ฐฑ์ ๋ฐ๋ฅด์ง ์๋๋ค
- ์ํ์ค๋ก ๋ฝ์ ๋ฒํธ๋ ๋์์ค์ง ์๋๋ค.
ROLLBACKํ์๋ ๋ค์ ๊ฐ์ ๊ทธ๋ค์ ๋ฒํธ๋ค- ํธ๋์ญ์ ์์ DB ์์ ๋ง ๋์ด์ผ ํ๋ ์ด์ ๊ฐ ์ฌ๊ธฐ ์๋ค
ACID๋ ํธ๋์ญ์ ์ด ์ง์ผ์ฃผ๋ ์ฑ์ง ๋ค ๊ฐ์ง๋ฅผ ๋ฌถ์ ์ฝ์๋ค.
2. A ยท C ยท I ยท D
๊ฐ ๊ธ์๊ฐ ๋ง๋ ์ํฉ์ด ๋ค๋ฅด๋ค.
| ์ด๋ฆ | ๋ง๋ ์ํฉ | ๋ด๋น | |
|---|---|---|---|
| A | Atomicity | ์ ๋ฐ๋ง ๋ฐ์๋ ์ํ | DB |
| C | Consistency | ์ ์ฝ์ ์ด๊ธด ์ํ | DB + ์ ํ๋ฆฌ์ผ์ด์ |
| I | Isolation | ๋จ์ ์์ ์ค๊ฐ์ด ๋ณด์ด๋ ์ํ | DB |
| D | Durability | ์ปค๋ฐํ๋๋ฐ ์ฌ๋ผ์ง๋ ์ํ | DB |
- Atomicity: ํธ๋์ญ์ ์์ ๋ฌธ์ฅ์ด ์ ๋ถ ์ฑ๊ณตํ๊ฑฐ๋ ์ ๋ถ ์ทจ์๋๋ค. ์ค๊ฐ ์ง์ ์ด ๋จ์ง ์๋๋ค
- Consistency: ํธ๋์ญ์
์ ํ๋ก ์ ์ฝ ์กฐ๊ฑด์ด ๊นจ์ง์ง ์๋๋ค.
NOT NULL,FOREIGN KEY,CHECK๊ฐ ์ฌ๊ธฐ ํด๋นํ๋ค - Isolation: ๋์์ ๋๋ ํธ๋์ญ์ ์ด ์๋ก์ ์ค๊ฐ ์ํ๋ฅผ ๋ณด์ง ์๋๋ค
- Durability: ์ปค๋ฐํ๋ค๊ณ ์๋ตํ์ผ๋ฉด ๊ทธ ์งํ ์ ์ ์ด ๋๋ ๋ฐ์ดํฐ๊ฐ ๋จ๋๋ค
C๋ ๋๋จธ์ง ์ ๊ณผ ์ฑ๊ฒฉ์ด ๋ค๋ฅด๋ค
- AยทIยทD๋ DB๊ฐ ์์์ ์งํจ๋ค. C๋ ์ ๋ฐ์ด ์ ํ๋ฆฌ์ผ์ด์ ๋ชซ์ด๋ค
- โ๊ณ์ข ์์ก์ ์ดํฉ์ด ๋ณํ์ง ์๋๋คโ ๊ฐ์ ๊ท์น์ DB๊ฐ ๋ชจ๋ฅธ๋ค. ๊ฐ๋ฐ์๊ฐ ๋ UPDATE๋ฅผ ํ ํธ๋์ญ์ ์ ๋ฃ์ด์ผ ์ง์ผ์ง๋ค
- DB๊ฐ ๋ณด์ฅํ๋ C๋ ์ ์ธํ ์ ์ฝ ์กฐ๊ฑด๊น์ง๋ค
- ๊ทธ๋์ C๋ฅผ ๋๊ณ โ์ฝ์(ACID)๋ฅผ ๋ง๋ค๋ ค๊ณ ๋ผ์ ๋ฃ์ ๊ธ์โ๋ผ๋ ํ์ด ๋ฐ๋ผ๋ค๋๋ค. ์ค์ ๋ก A์ D๊ฐ ์์ผ๋ฉด ๋๋ถ๋ถ ๋ฐ๋ผ์ค๋ ์ฑ์ง์ด๋ค
Durability: ์ด๋๊น์ง ์ผ์ ๋ ์ปค๋ฐ์ธ๊ฐ
- ์ปค๋ฐ ์์ ์ ๋ฐ์ดํฐ ํ์ผ์ ๊ณ ์น์ง ์๋๋ค. WAL(Write-Ahead Log)์ ๋ณ๊ฒฝ ๋ด์ญ์ ๋จผ์ ์ ๊ณ
fsync๋ก ๋์คํฌ์ ๋ฐ์ด ๋ฃ๋๋ค- ๋ฐ์ดํฐ ํ์ผ ๋ฐ์์ ๋์ค์ ๋ชฐ์์ ํ๋ค. ์์ฐจ ์ฐ๊ธฐ ํ ๋ฒ์ด ์์ ์์น ์ฐ๊ธฐ ์ฌ๋ฌ ๋ฒ๋ณด๋ค ๋น ๋ฅด๊ธฐ ๋๋ฌธ์ด๋ค
- ์ฃฝ์๋ค ์ด์๋๋ฉด WAL์ ์ฌ์ํด ๋ณต๊ตฌํ๋ค
fsync = off๋ก ๋๋ฉด ์ปค๋ฐ์ด ๋นจ๋ผ์ง๋ ๋์ D๋ฅผ ํฌ๊ธฐํ๋ค. ์ฌํ ๊ฐ๋ฅํ ๋ฐฐ์น ์ ์ฌ๊ฐ ์๋๋ฉด ์ผ๋๋ค
3. I๋ง ๋ฑ๊ธ์ด ์๋ ์ด์
A์ D๋ ์งํค๊ฑฐ๋ ์ ์งํค๊ฑฐ๋ ๋ ์ค ํ๋๋ค. ์ ๋ฐ๋ง ์์์ ์ธ ํธ๋์ญ์ ์ ์๋ค.
I๋ ๋ค๋ฅด๋ค. ์๋ฒฝํ ๊ฒฉ๋ฆฌ๋ ํธ๋์ญ์ ์ ํ ์ค๋ก ์ธ์ ํ๋์ฉ ์คํํ๋ ๊ฒ์ธ๋ฐ ๊ทธ๋ฌ๋ฉด ๋์ ์ฒ๋ฆฌ๋์ด ์ฌ๋ผ์ง๋ค.
- ์๋ฒฝํ ๊ฒฉ๋ฆฌ: T1 ๋ โ T2 ์์ โ T3 ์์. ์์ ํ์ง๋ง ๋๋ฆฌ๋ค
- ๋์จํ ๊ฒฉ๋ฆฌ: T1 T2 T3 ๋์ ์งํ. ๋น ๋ฅด์ง๋ง ์ด์ํ ๊ฐ์ด ๋ณด์ธ๋ค
๊ทธ๋์ ๊ฒฉ๋ฆฌ๋ง ์ด๋๊น์ง ํ์ฉํ ์ง ๊ณ ๋ฅด๋ ์์ก์ด๊ฐ ๋๋ค.
4. ์ธ ๊ฐ์ง ์ด์ ํ์
๊ฒฉ๋ฆฌ๋ฅผ ๋์จํ๊ฒ ํ๋ฉด ๋ํ๋๋ ํ์์ ์ด๋ฆ์ด ๋ถ์ด ์๋ค. ๊ฒฉ๋ฆฌ ์์ค์ ์ด ์ ์ค ๋ฌด์์ ๋ง๋๋๋ก ์ ์๋๋ค.
Dirty Read: ์ปค๋ฐ ์ ๋ ๊ฐ์ ์ฝ๋๋ค
T1 T2
------------------------ ------------------------
UPDATE balance = 500
SELECT balance --> 500
ROLLBACKT2๊ฐ ์ฝ์ 500์ ํ ๋ฒ๋ ํ์ ๋ ์ ์๋ ๊ฐ์ด๋ค.
Non-Repeatable Read: ๊ฐ์ ํ์ ๋ ๋ฒ ์ฝ์๋๋ฐ ๊ฐ์ด ๋ค๋ฅด๋ค
T1 T2
------------------------ ------------------------
SELECT balance --> 1000
UPDATE balance = 500
COMMIT
SELECT balance --> 500T1์ ์๋ฌด๊ฒ๋ ์ ํ๋๋ฐ ๊ฐ์ ์ง๋ฌธ์ ๋ต์ด ๋ฐ๋์๋ค.
Phantom Read: ๊ฐ์ ์กฐ๊ฑด์ผ๋ก ๋ ๋ฒ ์กฐํํ๋๋ฐ ํ ๊ฐ์๊ฐ ๋ค๋ฅด๋ค
T1 T2
----------------------------- -----------------------------
SELECT count(*) WHERE age > 30
--> 10
INSERT age = 35
COMMIT
SELECT count(*) WHERE age > 30
--> 11์๋ ํ์ด ๋ํ๋ฌ๋ค. ๋์์ ํน์ ํ์ด ์๋๋ผ ์กฐ๊ฑด์ ๋ง๋ ์งํฉ์ด๋ค.
Non-Repeatable Read์ Phantom์ ์ฐจ์ด
- Non-repeatable read: ์ด๋ฏธ ์ฝ์ ํ์ ๊ฐ์ด ๋ฐ๋๋ค. ๋์์ด ํน์ ํ์ด๋ค
- Phantom: ์กฐ๊ฑด์ ๋ง๋ ํ์ ์งํฉ์ด ๋ฐ๋๋ค. ๋์์ด ๋ฒ์๋ค
- ๋ง๋ ๋ฐฉ๋ฒ๋ ๋ค๋ฅด๋ค. ์์ ์ฝ์ ํ์ ๋ฝ์ ๊ฑธ๋ฉด ๋์ง๋ง ๋ค๋ ์์ง ์กด์ฌํ์ง ์๋ ํ์ด๋ผ ๊ฑธ ๋์์ด ์๋ค. ๊ทธ๋์ ๋ฒ์ ์์ฒด์ ๋ฝ์ ๊ฑธ๊ฑฐ๋ ์ค๋ ์ท์ ๊ณ ์ ํด์ผ ํ๋ค
5. ๊ฒฉ๋ฆฌ ์์ค ๋ค ๋จ๊ณ
ANSI SQL-92๊ฐ ๋ค ๋จ๊ณ๋ฅผ ์ ์ํ๋ค. ์๋ก ๊ฐ์๋ก ๋์จํ๊ณ ์๋๋ก ๊ฐ์๋ก ์๊ฒฉํ๋ค.
| ์์ค | Dirty Read | Non-Repeatable Read | Phantom |
|---|---|---|---|
| Read Uncommitted | ํ์ฉ | ํ์ฉ | ํ์ฉ |
| Read Committed | ๋ฐฉ์ง | ํ์ฉ | ํ์ฉ |
| Repeatable Read | ๋ฐฉ์ง | ๋ฐฉ์ง | ํ์ฉ |
| Serializable | ๋ฐฉ์ง | ๋ฐฉ์ง | ๋ฐฉ์ง |
- Read Uncommitted: ์ปค๋ฐ ์ ๊ฐ๊น์ง ๋ณด์ธ๋ค. ์ฐ๋ ๊ณณ์ด ๊ฑฐ์ ์๋ค
- Read Committed: ์ปค๋ฐ๋ ๊ฐ๋ง ์ฝ๋๋ค. ๋ฌธ์ฅ ํ๋๋ง๋ค ์ต์ ์ค๋ ์ท์ ์๋ก ๋ฌ๋ค
- Repeatable Read: ํธ๋์ญ์ ์์ ์์ ์ ์ค๋ ์ท์ ๋๊น์ง ์ ์งํ๋ค
- Serializable: ํธ๋์ญ์ ์ ํ๋์ฉ ์คํํ ๊ฒ๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฅํ๋ค
ํ๋ ๊ธ์ง ๋ชฉ๋ก์ด ์๋๋ผ ํ์ฉ ๋ชฉ๋ก์ด๋ค. ํ์ค์ โ์ด ์์ค์์ ์ด ํ์์ด ์ผ์ด๋ ์ ์๋คโ๊ณ ์ ํ ๋ฟ์ด๋ผ ๋ ์๊ฒฉํ๊ฒ ๊ตฌํํด๋ ๊ท๊ฒฉ ์๋ฐ์ด ์๋๋ค. ์ค์ DB๊ฐ ์ด ์ฌ์ง๋ฅผ ์ด๋ค.
6. ์ด๋ฆ๊ณผ ์ค์ ๋์์ด ๋ค๋ฅด๋ค
๊ฐ์ REPEATABLE READ๋ฅผ ๊ฑธ์ด๋ DB๋ง๋ค ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅด๋ค.
| ๊ธฐ๋ณธ๊ฐ | ํน์ด์ฌํญ | |
|---|---|---|
| PostgreSQL | Read Committed | Read Uncommitted๋ฅผ ์์ฒญํด๋ Read Committed๋ก ๋์. Repeatable Read์์ phantom๋ ๋งํ |
| MySQL InnoDB | Repeatable Read | gap lock์ผ๋ก phantom์ ๋์ฒด๋ก ๋ง์ |
| Oracle | Read Committed | Read Uncommitted์ Repeatable Read๋ฅผ ์์ ์ง์ํ์ง ์์ |
| SQL Server | Read Committed | ์ต์ ์ผ๋ก ์ค๋ ์ท ๊ธฐ๋ฐ ๋์ ์ ํ |
PostgreSQL์ Repeatable Read๋ ํ์ค์ด ์๊ตฌํ๋ ๊ฒ๋ณด๋ค ์๊ฒฉํ๋ค. ํธ๋์ญ์ ์์ ์์ ์ค๋ ์ท์ ๋๊น์ง ์ ์งํ๋ ๋ฐฉ์์ด๋ผ phantom๊น์ง ํจ๊ป ๋งํ๋ค.
-- ์ธ์
๋จ์๋ก ์ง์
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- ํธ๋์ญ์
ํ๋์๋ง ์ง์
BEGIN ISOLATION LEVEL SERIALIZABLE;
SELECT ...;
COMMIT;์ฃผ์: ์์ค ์ด๋ฆ์ผ๋ก ํ๋จํ์ง ์๋๋ค
- ์ด์์ฑ ์๋ ์ฝ๋๋ฅผ ์ฐ๋ ค๋ฉด ์ด๋ฆ์ด ์๋๋ผ โ์ด๋ค ์ด์ ํ์์ด ๋งํ๋๊ฐโ๋ฅผ ํ์ธํ๋ค
- MySQL์์ ๋๋ ๋ฐฐ์น๋ฅผ PostgreSQL๋ก ์ฎ๊ฒผ๋๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ ์ผ์ด ์ฌ๊ธฐ์ ์๊ธด๋ค
- ํนํ Repeatable Read๋ ๋ DB์ ๋์ ์ฐจ์ด๊ฐ ํฌ๋ค
7. ํ์ค์ ์๋ ์ด์ ํ์
ANSI๊ฐ ์ ์ํ ์ ์ผ๋ก๋ ๋ถ์กฑํ๋ค๋ ์ง์ ์ด 1995๋ ๋ ผ๋ฌธ์์ ๋์๋ค. ๋ํ๊ฐ write skew๋ค.
๋ณ์์ ๋น์ง ์์ฌ๊ฐ ์ต์ ํ ๋ช ์ ์์ด์ผ ํ๋ค๊ณ ํ์. ์ง๊ธ ๋ ๋ช ์ด ๋น์ง์ด๋ค.
T1 (doctor A) T2 (doctor B)
----------------------------- -----------------------------
SELECT count(*) WHERE on_call SELECT count(*) WHERE on_call
--> 2, so I can leave --> 2, so I can leave
UPDATE a SET on_call = false
UPDATE b SET on_call = false
COMMIT
COMMIT๋น์ง์ด 0๋ช ์ด ๋๋ค. ๋ ํธ๋์ญ์ ๋ชจ๋ ๊ท์น์ ํ์ธํ๊ณ ์ด๊ฒผ๋ค.
๊ฐ์ ํ์ ๊ณ ์น์ง ์์์ ์ถฉ๋๋ก ๊ฐ์ง๋์ง ์๋๋ค. Repeatable Read์์๋ ๊ทธ๋๋ก ์ผ์ด๋๋ค.
PostgreSQL์ Serializable์์ SSI(Serializable Snapshot Isolation)๋ก ์ด๋ฅผ ์ก๋๋ค.
ERROR: could not serialize access due to read/write dependencies among transactions
HINT: The transaction might succeed if retried.Serializable์ด ํ์ํ ์๋ฆฌ
- โ์กฐ๊ฑด์ ํ์ธํ๊ณ ๊ทธ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ์ด๋คโ๊ฐ ํ ํธ๋์ญ์ ์์ ์์ ๋๋ค. ๋น์ง ์์, ์ฌ๊ณ ํ์ธ ํ ์ฐจ๊ฐ, ์ค๋ณต ์์ฝ ๋ฐฉ์ง๊ฐ ์ฌ๊ธฐ ํด๋นํ๋ค
- ์กฐ๊ฑด ๊ฒ์ฌ ์์ด ๊ฐ๋ง ๊ฐฑ์ ํ๋ ์์ ์ Read Committed๋ก ์ถฉ๋ถํ๋ค
8. Serializable์ ๊ฑธ์ด๋๋ ๊ฒ์ผ๋ก ๋๋์ง ์๋๋ค
๊ฐ์ง๋ DB๊ฐ ์ ๋ถ ํ๊ณ ์คํจ ์ฒ๋ฆฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ ๋ถ ํ๋ค.
SELECT FOR UPDATE๋ ๊ฑธ์ด๋๋ฉด ๋์ด๋ค. ๊ธฐ๋ค๋ ธ๋ค๊ฐ ๊ฒฐ๊ตญ ์ฑ๊ณตํ๋ค. Serializable์ ๋ฐ๋๋ก ๊ฑธ์ด๋๋ ๊ฒ์ด ์์์ด๊ณ ์๋ฌ๋ฅผ ๋ฐ์์ค ์ฝ๋๊ฐ ์์ผ๋ฉด ๊ฐฑ์ ์ด ์กฐ์ฉํ ์ฌ๋ผ์ง๋ค.
์ฝ์ ์๋ฆฌ๋ฅผ ํ์ํด๋๊ณ ๋จ์ด ์ผ๋์ง๋ง ๋ณธ๋ค
SELECT count(*) FROM doctors WHERE on_call = true;
-- ์กฐ๊ฑด์ ๊ฑธ๋ฆฐ ์ธ๋ฑ์ค ํ์ด์ง์ ํํ์ SIReadLock ํ์๊ฐ ๋จ๋๋คSIReadLock์ ์ด๋ฆ์ด ๋ฝ์ด์ง๋ง ์๋ฌด๋ ๋ง์ง ์๋๋ค. โ๋ด๊ฐ ์ด๊ฑธ ์ฝ์๋คโ๋ ํ์ ์ผ ๋ฟ์ด๋ค. pg_locks์์ ํ์ธํ ์ ์๋ค.
SELECT locktype, relation::regclass, mode
FROM pg_locks WHERE mode = 'SIReadLock';์ดํ ๋ค๋ฅธ ํธ๋์ญ์ ์ด ๊ทธ ์๋ฆฌ์ ์ฐ๋ฉด ์ฝ๊ธฐยท์ฐ๊ธฐ ์์กด์ด ํ๋ ๊ธฐ๋ก๋๋ค. ์ด ์์กด์ด ํน์ ํํ๋ก ๋ง๋ฌผ๋ฆฌ๋ฉด ์ง๋ ฌ ์์๊ฐ ์กด์ฌํ ์ ์๋ค๊ณ ํ์ ํด ํ์ชฝ์ ์ทจ์ํ๋ค.
๊ฐ๋ฐ์ ๋ชซ ์ธ ๊ฐ์ง
์ฌ์๋ ์ฝ๋๋ฅผ ๋ถ์ธ๋ค
ํธ๋์ญ์ ์ ์ฒด๋ฅผ ๋ค์ ์คํํด์ผ ํ๋ค. ์ปค๋ฐ๋ง ๋ค์ ์๋ํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์๋ค. ์ฝ์ ๊ฐ ์์ฒด๊ฐ ๋ฌดํจ๋ผ์๋ค.
for _ in range(3):
try:
with conn.transaction(): # ISOLATION LEVEL SERIALIZABLE
if count_on_call() >= 2:
set_off_duty(me)
break
except psycopg.errors.SerializationFailure: # SQLSTATE 40001
continue
else:
raise RuntimeError("์ฌ์๋ ํ๋ ์ด๊ณผ")์ฌ์๋ ๋์ ์๋ฌ ๊ตฌ๋ถ๊ณผ ๋ถ์ ํจ๊ณผ ์ฒ๋ฆฌ๋ ์ฌ์๋ ๊ฐ๋ฅํ ํธ๋์ญ์ ์ค๊ณ์์ ๋ค๋ฃฌ๋ค.
์ฐธ์ฌํ๋ ํธ๋์ญ์ ์ ์ ๋ถ Serializable๋ก ๋ง์ถ๋ค
๊ฐ์ฅ ์์ฃผ ๋์น๋ ๋ถ๋ถ์ด๋ค. ๋ณด์ฅ ๋ฒ์๊ฐ โ์ปค๋ฐ์ ์ฑ๊ณตํ Serializable ํธ๋์ญ์ ์ฌ์ดโ๋ก ํ์ ๋๋ค.
T1 SERIALIZABLE SIReadLock์ ๋จ๊ธด๋ค --> ์ถ์ ๋์
T2 READ COMMITTED ํ์ ์ ์ ๋จ๊ธด๋ค --> ์ถ์ ๋์ ์๋T2๊ฐ ๊ท์น์ ๊นจ๋ T1์ ์์ง ๋ชปํ๋ค. ๊ฐ์ ํ ์ด๋ธ์ ๊ฑด๋๋ฆฌ๋ ๊ฒฝ๋ก๊ฐ ์ฌ๋ฟ์ด๋ฉด ๋ฐฐ์น ํ๋๊น์ง ์ ๋ถ ๋ง์ถฐ์ผ ํ๋ค.
์ปค๋ฐ ์ ์ ์ฝ์ ๊ฐ์ ๋ฐ์ผ๋ก ๋ด๋ณด๋ด์ง ์๋๋ค
Serializable์์๋ ์ทจ์์ ์ฌ์๋๊ฐ ์ ์ ํ๋ฆ์ด๋ค. ํธ๋์ญ์ ์ค๊ฐ์ ์ฝ์ ๊ฐ์ผ๋ก ์ธ๋ถ API๋ฅผ ํธ์ถํ๋ฉด ์ทจ์๋ ์๋์ ํธ์ถ๋ ๋ฐ์ ๋จ๊ณ ์ฌ์๋ ํ์๋งํผ ๊ฐ์ ํธ์ถ์ด ๋ฐ๋ณต๋๋ค. ์ธ๋ถ๋ก ๋๊ฐ๋ ๋์์ ์ปค๋ฐ ์ดํ๋ก ๋ฏธ๋ฃฌ๋ค.
์๋์ด๋ผ์ ์น๋ฅด๋ ๋๊ฐ
SSI๋ ๋ณด์์ ์ด๋ค. ์ง์ง ์ถฉ๋์ธ์ง ๋๊น์ง ๋ฐ์ง๋ ๋์ ์ํํด ๋ณด์ด๋ฉด ์๋ฅธ๋ค. ์ค์ ๋ก๋ ๋ฌธ์ ์์์ ํธ๋์ญ์ ๋ ์ทจ์๋๋ค.
์ฃผ์: ์์ฐจ ์ค์บ์ด ๊ฑฐ์ง ์์ฑ์ ํค์ด๋ค
- ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๋ฉด ํ ์ด๋ธ ์ ์ฒด์ ๊ด๊ณ ์์ค predicate lock์ด ๊ฑธ๋ ค ๋ฌด๊ดํ ํธ๋์ญ์ ๊น์ง ์ถฉ๋ํ๋ค. ์ธ๋ฑ์ค๋ฅผ ํ๋ฉด ํ์ด์ง๋ ํํ ๋จ์๋ก ์ขํ์ง๋ค
- predicate lock ํ ์ด๋ธ์ด ๋ฉ๋ชจ๋ฆฌ์ ๋ชจ์๋ผ๋ ๊ฐ์ ์ผ์ด ์๊ธด๋ค. ํ์ด์ง ๋จ์ ๋ฝ์ ๊ด๊ณ ๋จ์๋ก ํฉ์น๋ฉด์ ์ถฉ๋ ๋ฒ์๊ฐ ๋์ด์ง๋ค
max_pred_locks_per_transaction,max_pred_locks_per_relation,max_pred_locks_per_page๋ก ํ๋๋ฅผ ์ฌ๋ฆฐ๋ค- ์ ๋ํฌ ์ ์ฝ์ ๋ฏธ๋ฆฌ ํ์ธํ๊ณ ๋ฃ์๋๋ฐ๋ ์๋ฐ์ด ๋๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. PostgreSQL ๋ฌธ์์ ์ ํ ๊ฑฐ์ง ์์ฑ์ด๋ค
์ฝ๊ธฐ๋ง ํ๋ ํธ๋์ญ์
์ READ ONLY๋ฅผ ๋ถ์ธ๋ค. predicate lock์ ๋๋ถ๋ถ ๋จ๊ธฐ์ง ์์ ๋ถ๋ด์ด ์ค์ด๋ ๋ค.
BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY;9. ๊ฒฉ๋ฆฌ๋ฅผ ์ค์ ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ
์ง๊ธ๊น์ง๋ ๋ฌด์์ ๋ณด์ฅํ๋๊ฐ์๋ค. ์ด๋ป๊ฒ ๋ง๋ค์ด๋ด๋๊ฐ๋ ๋ณ๊ฐ ๋ฌธ์ ๋ค.
๊ฒฉ๋ฆฌ ์์ค ๋ฌด์์ ๋ณด์ฅํ ์ง ์ ํ๋ ๊ณ์ฝ
โ
๋์์ฑ ์ ์ด ๊ทธ ๊ณ์ฝ์ ์งํค๋ ์๋จ
locking ยท MVCC ยท OCCRead Committed ํ๋๋ฅผ ๋ง๋๋ ๋ฐ๋ ๋ฐฉ๋ฒ์ด ๊ฐ๋ฆฐ๋ค. ์ฝ๋ ํ๋ง๋ค ๋ฝ์ ๊ฑธ์ด ์ปค๋ฐ ์ ๊ฐ์ ์ ๊ทผ์ ๋ง๋ ๋ฐฉ๋ฒ์ด ์๊ณ ๋ฒ์ ์ ์ฌ๋ฌ ๊ฐ ์ ์งํด ์ปค๋ฐ๋ ๋ฒ์ ๋ง ๋ณด์ฌ์ฃผ๋ ๋ฐฉ๋ฒ์ด ์๋ค. ์์ด locking์ด๊ณ ๋ค๊ฐ MVCC๋ค.
๋์์ฑ ์ ์ด์์ ์ธ ๋ฐฉ์์ ๋ค๋ฃฌ๋ค.