TLDR;
เราเคยเล่าสั้นๆเกี่ยวกับ ACID ในบทความ สรุป PostgreSQL ไปแล้ว แต่บทความนี้เราจะมาขยายความเรื่องนี้ให้มากขึ้น
- Atomic: all operation succeed or none do
- Consistent (คนละ C กับใน CAP theorem): data will always be in a good state and never in am inconsistent state
- Isolated: transaction don’t interfere with one another
- Durable: committed transaction is safe even after a server crash
ในชีวิตจริงของระบบ data มักจะมีปัญหาต่างๆ ไม่ว่าจะเป็น
- database ทั้งส่วน software และ hardware อาจจะ fail เมื่อไรก็ได้
- application อาจ crash เมื่อไรก็ได้
- network ล้ม, เน็ตดับ
- client เข้ามา write ข้อมูลใน database พร้อมกัน ทำให้เกิด conflict
- client อ่านข้อมูลแล้วได้ข้อมูลไม่เท่ากัน
เพื่อแก้ไขปัญหาพวกนี้เพื่อให้ data มัน reliable ได้ จึงต้องมี mechanism เข้ามาจัดการ หนึ่งในวิธีนั้นคือ concept ของ Transaction
transaction คือ set ของ operations ที่ application ใช้ เช่น operation ในการ read และ write โดยที่บอกว่า transaction ไหนสำเร็จ (commit) หรือ fail (ก็จะ abort หรือ rollback ไป)
ตัวอย่างเช่น
ในกรณีที่มี transaction ที่ จะ transfer เงินไปกลับ 5000
BEGIN TRANSACTION; UPDATE account SET total=total+5000.0 WHERE account_id=1337; UPDATE account SET total=total-5000.0 WHERE account_id=1337;END;
แล้วในระหว่างที่กำลัง Update แรกและสอง, server ดันตายขึ้นมา แต่เมื่อถูก wrap ใน transaction ก็จะการันตีได้ว่า เงินทั้งหมดที่ต้อง Update ใน transaction นี้จะถูก rolled back
แม้จะมีบาง application ที่ไม่ใช้ mechanism ของ transaction เจ้าตัว transaction ก็ยังเป็นที่นิยมอยู่ดี เรามักจะพบใน relational database เกือบทั้งหมด (MySQL, PostgreSQL, Oracle, SQL Server) หรือใน non relational database บางตัว
และหนึ่งในการการันตีใน transaction ที่รู้จักกันคือ ACID ซึ่งเป็นตัวเอกในวันนี้ที่เราจะเล่านี่เอง
ACID ย่อมาจาก Atomicity, Consistency, Isolation, และ Durability ซึ่งคำนี้ถูกคิดค้นโดย Theo Härder และ Andreas Reuter
รู้หรือไม่: จุดเริ่มต้นของ RDBMS
ในปี 1974 IBM สร้าง database system ที่ชื่อว่า System R ซึ่งเป็น research project ที่สร้างขึ้นมาเป็น prototype แรกของ RDBMS, System R จึงเป็น system แรกที่ demonstrate ว่า RDBMS มี performance ของ transaction processing ที่ดีและมีการนำ SQL มาใช้
แต่ RDBMS แรกที่เป็น commercial นั้นคือ Multics Relational Data Store (ปี 1976) ถูกสร้างโดย Oracle ซึ่งถูกปล่อยออกมาในปี 1979
ซึ่งไม่เกี่ยวกับเนื้อหาหลักของเรา เพียงแต่ Theo Härder ก็เป็นหนึ่งในคนที่ร่วมพัฒนา System R ด้วย
เล่าต่อเรื่อง ACID
ACID ถูกพูดถึงบ่อยครั้ง และเป็นนิยามหนึ่งที่สร้างความสับสนให้หลายๆคน ด้วยเหตุที่ว่านิยามของคำว่า ACID ใน database หนึ่ง อาจจะไม่เท่า ACID อีก database หนึ่งก็ได้ เช่นตัว Isolation เป็นต้น
เวลาบอกว่า “ระบบนี้มีคุณสมบัติ ACID” ก็อาจจะไม่เป็นอย่างที่เราเข้าใจก็ได้ คำว่า ACID จึงกลายเป็นคำสร้าง marketing ไปอย่างช่วยไม่ได้
ดังนั้นเรามาเข้าใจนิยามของแต่ละตัวกัน
Atomicity
Atomic แปลว่า สิ่งที่เล็กไปกว่านี้ไม่ได้แล้ว
คำว่า Atomic นั้นถูกใช้ในเรื่อง multi-threaded programming ด้วย ว่าด้วยหนึ่ง thread จะไม่เห็นการระหว่างการทำงานของอีก thread หนึ่ง แต่นั่นไม่ใช่คำ Atomic ที่เราจะหมายถึงในนี้
Atomic นั้นไม่เกี่ยวกับ concurrency (แปล concurrency: multiple computations are happening at the same time) เพราะคำนี้มีความหมายเดียวกับใน I: Isolation
Atomicity คือ all changes happens or none happens
statement ใน transaction ที่จะ read, write, update หรือ delete มันคือสิ่งที่เล็กที่สุด (atomicity)
สมมติ client อยาก write ข้อมูล ทุก statements ทั้งหมดใน transaction ก็จะถูก execute ทั้งหมด
แต่หากเกิดปัญหาขึ้นอาทิเช่น เน็ตดับ, process crash กลางทาง, disk เต็ม หรือเหตุการณ์อะไรก็ตามที่มา interrupt ระหว่างนี้ transaction จะไม่ completed (committed) และ transaction นี้จะถูก aborted ไป
หากไม่มี Atomicity:
ก็อาจจะเกิดปัญหาตามมาเช่น ข้อมูลมี write ซ้ำ เกิด duplicate data ขึ้นในระบบก็ได้
วิธีคิดของ Atomicity นั้นง่ายมาก หากเกิดกรณี fault ก็ให้ abort จนน่าจะชื่อว่า Abortability มากกว่า 😂 (หนังสือเล่ามาว่างั้นจริงๆ)
Consistency
Consistency ก็เป็นอีกหนึ่งคำที่มีอยู่ทุกที่ จึงสร้างความสับสนไม่น้อย
หนึ่งในความสับสนนั้นก็รวมถึงตัว C ใน CAP theorem แต่มันไม่ใช่สิ่งเดียวกัน
Consistency ในหลักของ ACID แปลว่า data must always be true (invariant) ข้อมูลเราถูกต้องเสมอ
ตัวอย่างเช่น ในระบบของบัญชี, เดบิต, เครดิต ตัวเลขข้างในต้องมี balance เท่ากันและเชื่อถือได้เสมอ
นั่นคือสิ่งที่ application ทำได้ ว่า transaction จะต้องถูกต้องเพื่อรักษาความ consistency เอาไว้ (แต่ถ้าเราเขียนอะไรผิดๆลงไป database ก็ห้ามไม่ได้อยู่ดีนะ อยากมากก็แค่เช็ค Foreign keyให้ อะไรก็ว่าไป)
ดังนั้น Consistency จึงเป็นตัวเดียวในหมู่ A, I, D ที่เหลือที่พูดถึง Applicationในขณะที่ตัวอื่นพูดถึงคุณสมบัติของ database
Application นั้นขึ้นอยู่กับ Database ที่มีความ Atomicity + Isolation เพื่อนำไปสู่ความ Consistency
ในหนังสือมีระบุเพิ่มไว้ว่า ใน paper ของ Härder และ Reuter กล่าวไว้ว่าตัว C มีไว้เพื่อ “tossed in to make the acronym works” ซะด้วยซ้ำ
รู้หรือไม่: CAP vs ACID
CAP กับ ACID แชร์ศัพท์เหมือนกัน เช่น คำว่า Consistency เป็นคำเดียวกัน แต่ความหมายต่างกัน จึงมักสร้างความสับสนให้หลายคนไม่น้อย
เพราะที่มาของแต่ละตัวมาจากคอนเซปที่ต่างกัน CAP นั้นมาจาก distributed system theory ในขณะที่ ACID พูดถึง database system
Consistency ใน CAP นั้นคือการที่ทุก replica ที่อยู่กระจัดกระจายทั่ว node สามารถ read แล้วได้ค่าที่ล่าสุดเสมอ
Isolation
Isolation แปลว่า ออกจากกัน (เหมือน home isolation ที่ต้องกักตัวแยกออกมาเวลาเป็นโควิดนั่นแหล่ะ) มาใช้อธิบายในกรณีที่มี client หลายคนเข้ามาใช้ database พร้อมๆกัน (Race condition)
สมมติว่า 2 คนที่ตั้งใจเข้ามา read data จาก database และได้ค่า 1 ออกมาแล้วพยายามจะ write data กลับด้วยการ +1
แต่ผลที่เกิดขึ้นคือค่าที่ถูกเก็บจะเป็น 2 ไม่ใช่ 3 เนื่องจาก database รู้ว่าเกิด race condition ขึ้น

หากยังจำคำว่า concurrency ที่กล่าวใน Atomicity ข้างบนได้
Isolation ใน ACID คือการ concurrently execute transaction
โดยที่แต่ละ transaction จะ isolate กันและกัน (อย่าง client คนแรกกับคนที่ 2 จะไม่ได้ทำให้ค่ารวมเป็น 3)
ในหนังสือบางเล่ม isolation ถูกใช้แทนเป็นคำว่า serializability นั่นคือหาก transaction committed ไปแล้ว ค่าที่ได้จาก database ยังคงเหมือนเดิมแม้ client เข้ามารันแบบ serially (one after another)
Durability
Durability คือความการันตีว่า data ที่ถูกเก็บจะไม่หายไปไหนเมื่อ transaction นั้นถูก committed ไปแล้ว
แม้ว่า hardware เกิดความผิดปกติ เช่น เน็ตจะหลุด ไฟจะดับ
ตัวอย่างเช่น ถ้าเป็น Durability ในเรื่องของ replication มันคือการที่ data ถูก copy จาก node หนึ่งไปยังอีก node หนึ่งแบบ success
ซึ่ง database ต้องมั่นใจว่า การเขียนเสร็จสิ้นแล้ว หรือ replicate เสร็จแล้วก่อนที่จะ commit transaction
เช่น หากเรา write data ลง disk แล้ว machine ตาย แปลว่า data เราไม่ได้หายไปไหน แต่เพียงแค่เรา access ไม่ได้เฉยๆ หาก machine เรากลับมาก็สามารถใช้งานได้เหมือนเดิม
แต่นั่นก็เป็นเพียงคุณสมบัติของ transaction เท่านั้น เพราะในชีวิตจริง perfect durability นั้นไม่มีอยู่จริง หากมีวันนึงที่มีคนลบ hard disk ไปพร้อมๆกับ backup อันนี้ไม่ใช่เรื่องของ transaction ละ นี่เรียกหายนะ
รู้หรือไม่: ACID vs BASE
System ที่ไม่ได้ meet คุณสมบัติของ ACID จะถูกเรียก(แบบติดตลก) ว่า BASE (กรด-เบสไง) ซึ่งย่อมาจาก Basically Available, Soft state, และ Eventual Consistency
สรุป
ในบทความนี้เราได้เล่าว่า mechanism ในการทำ reliability data นั้นคือ transaction โดย 1 ในวิธีการันตีของ transaction คือ ACID โดยประกอบไปด้วย Atomicity, Consistency, Isolation และ Durability
ตัว A, I, D พูดถึงคุณสมบัติของ database ในขณะที่ Consistency พูดในแง่ของ application
และหลายครั้งที่คำพวกนี้ถูกใช้ซ้ำหลายที่แต่ความหมายไม่เหมือนกัน เช่น Consistency, หรือความหมายเดียวกันแต่ใช้คนละคำ เช่น Isolation และ serialization
หวังว่าบทความนี้จะเป็นประโยชน์นะคะ หากมีคำแนะนำหรือแจ้งคำผิด สามารถแจ้งมาได้ที่ https://www.facebook.com/mesodiar คร้าบ
ref:
- Designing Data-Intensive Application Chapter 7
- https://en.wikipedia.org/wiki/Relational_database
- http://blog.thislongrun.com/2015/03/the-confusing-cap-and-acid-wording.html
- https://en.wikipedia.org/wiki/IBM_System_R
- https://en.wikipedia.org/wiki/Theo_Härder

Leave a comment