Transaction Isolation
กลไกที่ควบคุมว่า transaction ที่ทำงานพร้อมกัน เห็น changes ของกันและกันแค่ไหน — ระดับสูงขึ้น = ปลอดภัยขึ้น แต่ช้าลง
4 Read Phenomena (ปรากฏการณ์ที่อาจเกิด)
1. Dirty Read
อ่านค่าที่อีก transaction เขียนแต่ยังไม่ commit → ถ้า rollback → ค่าที่อ่านมาผิด
2. Non-Repeatable Read
อ่าน row เดียวกัน 2 ครั้งใน transaction เดียว ได้ค่าต่างกัน — เพราะมี transaction อื่น commit update ระหว่างนั้น
3. Phantom Read
รัน range query 2 ครั้ง ได้จำนวนแถวต่างกัน — เพราะมี transaction อื่น INSERT row ใหม่ที่ตกอยู่ใน range
4. Lost Update
2 transaction เขียนแถวเดียวกันพร้อมกัน → update ของฝั่งหนึ่งหายไป
4 Isolation Levels (มาตรฐาน SQL)
| ระดับ | Dirty Read | Lost Update | Non-Repeatable | Phantom |
|---|---|---|---|---|
| Read Uncommitted | อาจเกิด | อาจเกิด | อาจเกิด | อาจเกิด |
| Read Committed | ป้องกัน | อาจเกิด | อาจเกิด | อาจเกิด |
| Repeatable Read | ป้องกัน | ป้องกัน | ป้องกัน | อาจเกิด |
| Serializable | ป้องกัน | ป้องกัน | ป้องกัน | ป้องกันทั้งหมด |
Snapshot Isolation
แต่ละ transaction เห็น state ของ DB ณ เวลาเริ่ม transaction — PostgreSQL ใช้กลไกนี้สำหรับ Repeatable Read → ป้องกัน phantom read ได้ด้วย (เกินมาตรฐาน SQL)
Implementation: Pessimistic vs Optimistic
Pessimistic (ใช้ locks)
- ใช้ row/table/page lock ป้องกันการชน
- ปลอดภัย แต่ช้าและเสี่ยง deadlock
- ตัวอย่าง:
SELECT ... FOR UPDATE
Optimistic (ใช้ versioning)
- ไม่ lock — track version ของแต่ละ row
- ถ้าชนตอน commit → fail → caller retry
- ตัวอย่าง: version column +
WHERE version = <old>
MVCC (Multi-Version Concurrency Control)
- PostgreSQL ใช้ MVCC — เก็บหลาย version ของแถว
- Writer ไม่ block reader — reader เห็น version เก่า, writer เขียน version ใหม่
- Postgres: tuple versioning ใน heap (row เก่ายังอยู่จนกว่า VACUUM)
- MySQL InnoDB: ใช้ undo log เก็บ old version แยก
Pitfall ที่เจอบ่อย
ตั้ง isolation level สูงเกินไป (เช่น Serializable ทุก transaction) → DB ช้าลงมาก
แนวทาง: ส่วนใหญ่ Read Committed เพียงพอ — ใช้ Serializable เฉพาะที่จำเป็นจริง ๆ (เช่น banking, inventory)
Key Points
- 4 Read Phenomena: Dirty Read, Non-repeatable Read, Phantom Read, Lost Update
- 4 Isolation Levels: Read Uncommitted → Read Committed → Repeatable Read → Serializable
- Snapshot Isolation ให้ transaction เห็น DB state ณ เวลาเริ่ม — Postgres ใช้วิธีนี้
- MVCC = writer ไม่ block reader → concurrency ดี
- ส่วนใหญ่ Read Committed เพียงพอ — อย่าใช้ Serializable ทุก transaction
Related
- ACID — Isolation เป็น “I” ใน ACID
- Concurrency Control — locks ที่ enforce isolation levels
- PostgreSQL — ใช้ MVCC + Snapshot Isolation
- MySQL — InnoDB ใช้ MVCC + Undo Log