5.1 ประเด็นเรื่องความพร้อมกัน

เริ่มจากทฤษฎีที่ห่างไกลกันสักหน่อย

ระบบข้อมูลใดๆ (หรือเรียกง่ายๆ ก็คือ แอปพลิเคชัน) ที่โปรแกรมเมอร์สร้างขึ้นประกอบด้วยบล็อกทั่วไปหลายบล็อก ซึ่งแต่ละบล็อกมีฟังก์ชันการทำงานที่จำเป็นส่วนหนึ่ง ตัวอย่างเช่น แคชใช้เพื่อจดจำผลลัพธ์ของการดำเนินการที่ใช้ทรัพยากรมากเพื่อให้แน่ใจว่าไคลเอ็นต์อ่านข้อมูลได้เร็วขึ้น เครื่องมือประมวลผลสตรีมช่วยให้คุณส่งข้อความไปยังคอมโพเนนต์อื่นสำหรับการประมวลผลแบบอะซิงโครนัส และเครื่องมือประมวลผลแบบแบตช์ใช้เพื่อ " คราด" ปริมาณข้อมูลที่สะสมด้วยระยะเวลาหนึ่ง .

และในเกือบทุกแอปพลิเคชัน ฐานข้อมูล (DBs) มีส่วนเกี่ยวข้องไม่ทางใดก็ทางหนึ่ง ซึ่งโดยปกติแล้วจะทำหน้าที่สองอย่าง: เก็บข้อมูลเมื่อได้รับจากคุณ และให้ข้อมูลเหล่านั้นแก่คุณในภายหลังเมื่อมีการร้องขอ ไม่ค่อยมีใครคิดสร้างฐานข้อมูลของตัวเอง เพราะมี Solution สำเร็จรูปมากมายอยู่แล้ว แต่คุณจะเลือกอย่างไรให้เหมาะกับใบสมัครของคุณ?

ลองนึกภาพว่าคุณเขียนแอปพลิเคชันด้วยอินเทอร์เฟซมือถือที่ให้คุณโหลดรายการงานที่บันทึกไว้ก่อนหน้านี้รอบ ๆ บ้าน นั่นคืออ่านจากฐานข้อมูลและเสริมด้วยงานใหม่ ๆ รวมถึงจัดลำดับความสำคัญของแต่ละรายการ งาน - จาก 1 ( สูงสุด) ถึง 3 (ต่ำสุด) สมมติว่าแอปพลิเคชันมือถือของคุณถูกใช้งานโดยผู้ใช้ครั้งละหนึ่งคนเท่านั้น แต่ตอนนี้คุณกล้าที่จะบอกแม่ของคุณเกี่ยวกับสิ่งที่คุณสร้าง และตอนนี้เธอได้กลายเป็นผู้ใช้ประจำคนที่สอง จะเกิดอะไรขึ้นถ้าคุณตัดสินใจในเวลาเดียวกัน ในมิลลิวินาทีเดียวกัน เพื่อกำหนดงานบางอย่าง - "ล้างหน้าต่าง" - ให้มีความสำคัญในระดับอื่น

ในแง่วิชาชีพ การสืบค้นฐานข้อมูลของคุณและมารดาถือเป็น 2 กระบวนการที่ทำแบบสอบถามไปยังฐานข้อมูล กระบวนการคือเอนทิตีในโปรแกรมคอมพิวเตอร์ที่สามารถทำงานบนเธรดตั้งแต่หนึ่งเธรดขึ้นไป โดยทั่วไปแล้ว กระบวนการจะมีอิมเมจรหัสเครื่อง หน่วยความจำ บริบท และทรัพยากรอื่นๆ กล่าวอีกนัยหนึ่ง กระบวนการสามารถกำหนดได้ว่าเป็นการดำเนินการตามคำสั่งของโปรแกรมบนโปรเซสเซอร์ เมื่อแอปพลิเคชันของคุณส่งคำขอไปยังฐานข้อมูล เรากำลังพูดถึงความจริงที่ว่าฐานข้อมูลของคุณประมวลผลคำขอที่ได้รับผ่านเครือข่ายจากกระบวนการหนึ่ง หากมีผู้ใช้สองคนนั่งอยู่ในแอปพลิเคชันพร้อมกัน อาจมีสองกระบวนการ ณ ช่วงเวลาใดเวลาหนึ่ง

เมื่อกระบวนการบางอย่างทำการร้องขอไปยังฐานข้อมูล กระบวนการนั้นจะพบว่าอยู่ในสถานะที่แน่นอน ระบบสถานะคือระบบที่จดจำเหตุการณ์ก่อนหน้าและเก็บข้อมูลบางอย่าง ซึ่งเรียกว่า "สถานะ" ตัวแปรที่ประกาศเป็นintegerสามารถมีสถานะเป็น 0, 1, 2 หรือพูด 42 Mutex (การยกเว้นร่วมกัน) มีสองสถานะ: ล็อคหรือปลดล็อคเช่นเดียวกับสัญญาณไบนารี ("จำเป็น" กับ "ปล่อย") และไบนารีโดยทั่วไป (ไบนารี) ชนิดข้อมูลและตัวแปรที่สามารถมีได้เพียงสองสถานะ - 1 หรือ 0

ตามแนวคิดของรัฐ โครงสร้างทางคณิตศาสตร์และวิศวกรรมหลายอย่างมีพื้นฐาน เช่น หุ่นยนต์ที่มีขอบเขตจำกัด ซึ่งเป็นแบบจำลองที่มีหนึ่งอินพุตและหนึ่งเอาต์พุต และอยู่ในชุดของสถานะที่จำกัดในแต่ละช่วงเวลา และ "สถานะ ” รูปแบบการออกแบบ ซึ่งวัตถุจะเปลี่ยนพฤติกรรมโดยขึ้นอยู่กับสถานะภายใน (เช่น ขึ้นอยู่กับค่าที่กำหนดให้กับตัวแปรหนึ่งหรือตัวแปรอื่น)

ดังนั้น อ็อบเจกต์ส่วนใหญ่ในโลกของเครื่องจักรจึงมีสถานะบางอย่างที่สามารถเปลี่ยนแปลงได้เมื่อเวลาผ่านไป: ไปป์ไลน์ของเราซึ่งประมวลผลแพ็กเก็ตข้อมูลขนาดใหญ่ ส่งข้อผิดพลาดและล้มเหลว หรือคุณสมบัติอ็อบเจกต์ Wallet ซึ่งเก็บจำนวนเงินที่เหลืออยู่ในบัญชีของผู้ใช้ บัญชี การเปลี่ยนแปลงหลังจากได้รับเงินเดือน

การเปลี่ยนผ่าน (“การเปลี่ยนผ่าน”) จากสถานะหนึ่งไปสู่อีกสถานะหนึ่ง—กล่าวคือ จากกำลังดำเนินการไปสู่ความล้มเหลว —เรียกว่าการดำเนินการ อาจเป็นไปได้ว่าทุกคนรู้จัก การทำงานของCRUD - create, read, update, deleteหรือ เมธอด HTTP ที่คล้าย กัน- POST, GET, PUT, DELETEแต่โปรแกรมเมอร์มักจะให้ชื่ออื่นแก่การดำเนินการในรหัส เนื่องจากการดำเนินการอาจซับซ้อนกว่าการอ่านค่าบางอย่างจากฐานข้อมูล - นอกจากนี้ยังสามารถตรวจสอบข้อมูลและการดำเนินการของเราซึ่งมีรูปแบบเป็นฟังก์ชัน จะถูกเรียกเช่น และvalidate()ใครเป็นผู้ดำเนินการเหล่านี้? กระบวนการที่อธิบายไว้แล้ว

อีกหน่อยแล้วคุณจะเข้าใจว่าทำไมฉันถึงอธิบายคำศัพท์อย่างละเอียด!

การดำเนินการใดๆ - ไม่ว่าจะเป็นฟังก์ชันหรือในระบบแบบกระจาย การส่งคำขอไปยังเซิร์ฟเวอร์อื่น - มี 2 คุณสมบัติ: เวลาการร้องขอและเวลาเสร็จสิ้น (เวลาเสร็จสิ้น)ซึ่งจะมากกว่าเวลาการร้องขออย่างเคร่งครัด (นักวิจัยจาก Jepsen ดำเนินการตามสมมติฐานทางทฤษฎีที่การประทับเวลาทั้งสองนี้จะได้รับนาฬิกาในจินตนาการที่ซิงโครไนซ์อย่างสมบูรณ์และพร้อมใช้งานทั่วโลก)

ลองนึกภาพแอปพลิเคชันรายการสิ่งที่ต้องทำของเรา คุณส่งคำขอไปยังฐานข้อมูลผ่านอินเทอร์เฟซมือถือใน14:00:00.014และแม่ของคุณใน13:59:59.678(นั่นคือ 336 มิลลิวินาทีก่อนหน้า) อัปเดตรายการสิ่งที่ต้องทำผ่านอินเทอร์เฟซเดียวกัน โดยเพิ่มจานซักเข้าไป คำนึงถึงความล่าช้าของเครือข่ายและคิวงานที่เป็นไปได้สำหรับฐานข้อมูลของคุณ หากนอกจากคุณและแม่ของคุณแล้ว เพื่อนของแม่ทุกคนยังใช้แอปพลิเคชันของคุณด้วย ฐานข้อมูลสามารถดำเนินการตามคำขอของแม่หลังจากที่ประมวลผลคำขอของคุณ กล่าวอีกนัยหนึ่งคือ มีโอกาสที่คำขอของคุณ 2 รายการ รวมถึงคำขอจากแม่ของแฟน จะถูกส่งไปยังข้อมูลเดียวกันในเวลาเดียวกัน (พร้อมกัน)

ดังนั้นเราจึงมาถึงคำศัพท์ที่สำคัญที่สุดในด้านฐานข้อมูลและแอปพลิเคชันแบบกระจาย - การทำงานพร้อมกัน การดำเนินการพร้อมกันสองรายการหมายความว่าอย่างไร หากกำหนดการดำเนินการบางอย่าง T1 และการดำเนินการบางอย่าง T2 แล้ว:

  • T1 สามารถเริ่มต้นก่อนเวลาเริ่มต้นของการดำเนินการ T2 และสิ้นสุดระหว่างเวลาเริ่มต้นและสิ้นสุดของ T2
  • สามารถเริ่ม T2 ได้ก่อนเวลาเริ่มต้นของ T1 และเสร็จสิ้นระหว่างจุดเริ่มต้นและจุดสิ้นสุดของ T1
  • T1 สามารถเริ่มต้นและสิ้นสุดระหว่างเวลาเริ่มต้นและสิ้นสุดของการดำเนินการ T1
  • และสถานการณ์อื่นๆ ที่ T1 และ T2 มีเวลาดำเนินการร่วมกัน

เป็นที่ชัดเจนว่าภายในกรอบของการบรรยายนี้ เรากำลังพูดถึงการสืบค้นข้อมูลเข้าสู่ฐานข้อมูลเป็นหลัก และวิธีการที่ระบบจัดการฐานข้อมูลรับรู้การสืบค้นเหล่านี้ แต่คำว่า การทำงานพร้อมกันนั้นมีความสำคัญ ตัวอย่างเช่น ในบริบทของระบบปฏิบัติการ ฉันจะไม่เบี่ยงเบนไปจากหัวข้อของบทความนี้มากนัก แต่ฉันคิดว่าสิ่งสำคัญคือต้องระบุว่าภาวะพร้อมกันที่เรากำลังพูดถึงนี้ไม่เกี่ยวข้องกับภาวะกลืนไม่เข้าคายไม่ออกของภาวะพร้อมกันและภาวะพร้อมกัน และความแตกต่างซึ่งกล่าวถึงในบริบท ของระบบปฏิบัติการและคอมพิวเตอร์ประสิทธิภาพสูง การทำงานแบบขนานเป็นวิธีหนึ่งในการบรรลุการทำงานพร้อมกันในสภาพแวดล้อมที่มีหลายคอร์ โปรเซสเซอร์ หรือคอมพิวเตอร์ เรากำลังพูดถึงการทำงานพร้อมกันในแง่ของการเข้าถึงกระบวนการต่างๆ ไปยังข้อมูลทั่วไปพร้อมกัน

และในความเป็นจริงแล้วอะไรที่สามารถผิดพลาดได้ในทางทฤษฎีอย่างหมดจด?

เมื่อทำงานกับข้อมูลที่ใช้ร่วมกัน ปัญหามากมายที่เกี่ยวข้องกับการทำงานพร้อมกัน หรือที่เรียกว่า "สภาวะการแข่งขัน" อาจเกิดขึ้นได้ ปัญหาแรกเกิดขึ้นเมื่อกระบวนการได้รับข้อมูลที่ไม่ควรได้รับ: ข้อมูลไม่สมบูรณ์ ชั่วคราว ถูกยกเลิก หรือ "ไม่ถูกต้อง" ปัญหาที่สองคือเมื่อกระบวนการได้รับข้อมูลเก่า นั่นคือข้อมูลที่ไม่สอดคล้องกับสถานะที่บันทึกไว้ล่าสุดของฐานข้อมูล สมมติว่าบางแอปพลิเคชันได้ถอนเงินจากบัญชีของผู้ใช้ด้วยยอดคงเหลือเป็นศูนย์ เนื่องจากฐานข้อมูลส่งคืนสถานะบัญชีไปยังแอปพลิเคชัน โดยไม่ได้คำนึงถึงการถอนเงินครั้งล่าสุดซึ่งเกิดขึ้นเมื่อไม่กี่มิลลิวินาทีที่แล้ว สถานการณ์ก็พอดูได้ใช่ไหม?

5.2 การทำธุรกรรมมาช่วยเรา

เพื่อแก้ปัญหาดังกล่าวแนวคิดของการทำธุรกรรมปรากฏขึ้น - กลุ่มของการดำเนินการตามลำดับ (การเปลี่ยนแปลงสถานะ) พร้อมฐานข้อมูลซึ่งเป็นการดำเนินการเดี่ยวแบบลอจิคัล ฉันจะยกตัวอย่างกับธนาคารอีกครั้ง - ไม่ใช่โดยบังเอิญเพราะแนวคิดของการทำธุรกรรมปรากฏขึ้นอย่างชัดเจนในบริบทของการทำงานกับเงิน ตัวอย่างคลาสสิกของธุรกรรมคือการโอนเงินจากบัญชีธนาคารหนึ่งไปยังอีกบัญชีหนึ่ง คุณต้องถอนเงินจำนวนดังกล่าวออกจากบัญชีต้นทางก่อนแล้วจึงฝากเข้าบัญชีเป้าหมาย

สำหรับการทำธุรกรรมนี้ แอปพลิเคชันจะต้องดำเนินการหลายอย่างในฐานข้อมูล: ตรวจสอบยอดคงเหลือของผู้ส่ง, บล็อกจำนวนเงินในบัญชีของผู้ส่ง, เพิ่มจำนวนเงินในบัญชีของผู้รับ และหักจำนวนเงินจากผู้ส่ง จะมีข้อกำหนดหลายประการสำหรับการทำธุรกรรมดังกล่าว ตัวอย่างเช่น แอปพลิเคชันไม่สามารถรับข้อมูลที่ล้าสมัยหรือไม่ถูกต้องเกี่ยวกับยอดคงเหลือ - ตัวอย่างเช่น หากในเวลาเดียวกันการทำธุรกรรมคู่ขนานสิ้นสุดลงด้วยข้อผิดพลาดกลางทาง และเงินไม่ถูกหักออกจากบัญชี - และแอปพลิเคชันของเราได้รับข้อมูลแล้ว ว่าเงินถูกตัดออก

เพื่อแก้ปัญหานี้ คุณสมบัติของธุรกรรมเช่น "การแยก" ถูกเรียกใช้: ธุรกรรมของเราดำเนินการราวกับว่าไม่มีธุรกรรมอื่นที่กำลังดำเนินการในเวลาเดียวกัน ฐานข้อมูลของเราดำเนินการพร้อมกันราวกับว่ากำลังดำเนินการทีละขั้นตอนตามลำดับ อันที่จริง ระดับการแยกสูงสุดเรียกว่าStrict Serializable ใช่ สูงสุด ซึ่งหมายความว่ามีหลายระดับ

"หยุด" คุณพูด ควบม้าของคุณนาย

จำวิธีที่ฉันอธิบายไว้ว่าแต่ละการดำเนินการมีเวลาเรียกและเวลาดำเนินการ เพื่อความสะดวก คุณสามารถพิจารณาเรียกและดำเนินการเป็น 2 การกระทำ จากนั้นรายการที่เรียงลำดับของการโทรและการดำเนินการทั้งหมดสามารถเรียกว่าประวัติของฐานข้อมูล จากนั้นระดับการแยกธุรกรรมจะเป็นชุดของประวัติ เราใช้ระดับความโดดเดี่ยวเพื่อตัดสินว่าเรื่องราวใด "ดี" เมื่อเราพูดว่าเรื่องราว "ทำลายความสามารถในการทำให้เป็นอนุกรม" หรือ "ไม่สามารถทำให้เป็นอนุกรมได้" เราหมายความว่าเรื่องราวนั้นไม่อยู่ในชุดของเรื่องราวที่ต่อเนื่องได้

เพื่อให้ชัดเจนว่าเรากำลังพูดถึงเรื่องราวประเภทใด ฉันจะยกตัวอย่าง ตัวอย่างเช่น มีประวัติประเภทนี้ - ระดับกลาง อ่าน . เกิดขึ้นเมื่อธุรกรรม A ได้รับอนุญาตให้อ่านข้อมูลจากแถวที่ได้รับการแก้ไขโดยธุรกรรม B ที่รันอยู่อีกรายการหนึ่ง และยังไม่ได้คอมมิต ("ไม่คอมมิท") - นั่นคือ อันที่จริง การเปลี่ยนแปลงยังไม่ได้ถูกคอมมิตในที่สุดโดย ธุรกรรม B และสามารถยกเลิกได้ตลอดเวลา และตัวอย่างเช่นการอ่านที่ถูกยกเลิกเป็นเพียงตัวอย่างของเราที่มีรายการถอนเงินที่ถูกยกเลิก

มีความผิดปกติหลายอย่างที่เป็นไปได้ นั่นคือ ความผิดปกติคือสถานะข้อมูลที่ไม่พึงประสงค์บางประเภทที่สามารถเกิดขึ้นได้ในระหว่างการแข่งขันในการเข้าถึงฐานข้อมูล และเพื่อหลีกเลี่ยงบางสถานะที่ไม่ต้องการ ฐานข้อมูลจะใช้ระดับการแยกที่แตกต่างกัน นั่นคือ ระดับการป้องกันข้อมูลที่แตกต่างกันจากสถานะที่ไม่ต้องการ ระดับเหล่านี้ (4 ชิ้น) ถูกระบุไว้ในมาตรฐาน ANSI SQL-92

คำอธิบายของระดับเหล่านี้ดูเหมือนคลุมเครือสำหรับนักวิจัยบางคน และพวกเขาเสนอการจำแนกประเภทของตนเองที่มีรายละเอียดมากขึ้น ฉันแนะนำให้คุณใส่ใจกับ Jepsen ที่กล่าวถึงแล้ว เช่นเดียวกับโครงการ Hermitage ซึ่งมีจุดมุ่งหมายเพื่อชี้แจงให้ชัดเจนว่า DBMS ใดเสนอระดับการแยกเช่น MySQL หรือ PostgreSQL หากคุณเปิดไฟล์จากที่เก็บนี้ คุณจะเห็นลำดับของคำสั่ง SQL ที่พวกเขาใช้เพื่อทดสอบฐานข้อมูลสำหรับความผิดปกติบางอย่าง และคุณสามารถทำสิ่งที่คล้ายกันกับฐานข้อมูลที่คุณสนใจได้) นี่คือตัวอย่างหนึ่งจากพื้นที่เก็บข้อมูลที่จะทำให้คุณสนใจ:

-- Database: MySQL

-- Setup before test
create table test (id int primary key, value int) engine=innodb;
insert into test (id, value) values (1, 10), (2, 20);

-- Test the "read uncommited" isolation level on the "Intermediate Reads" (G1b) anomaly
set session transaction isolation level read uncommitted; begin; -- T1
set session transaction isolation level read uncommitted; begin; -- T2
update test set value = 101 where id = 1; -- T1
select * from test; -- T2. Shows 1 => 101
update test set value = 11 where id = 1; -- T1
commit; -- T1
select * from test; -- T2. Now shows 1 => 11
commit; -- T2

-- Result: doesn't prevent G1b

สิ่งสำคัญคือต้องเข้าใจว่าสำหรับฐานข้อมูลเดียวกัน ตามกฎแล้วคุณสามารถเลือกการแยกได้หลายประเภท ทำไมไม่เลือกฉนวนที่แข็งแรงที่สุด? เพราะเช่นเดียวกับทุกอย่างในวิทยาการคอมพิวเตอร์ ระดับการแยกที่เลือกควรสอดคล้องกับการแลกเปลี่ยนที่เราพร้อมที่จะทำ - ในกรณีนี้ การแลกเปลี่ยนความเร็วในการดำเนินการ: ยิ่งระดับการแยกแข็งแกร่ง คำขอก็จะช้าลง แปรรูป. เพื่อให้เข้าใจว่าคุณต้องการการแยกระดับใด คุณต้องเข้าใจข้อกำหนดสำหรับแอปพลิเคชันของคุณ และเพื่อให้เข้าใจว่าฐานข้อมูลที่คุณเลือกมีระดับนี้หรือไม่ คุณจะต้องดูเอกสารประกอบ - สำหรับแอปพลิเคชันส่วนใหญ่จะเพียงพอ แต่ หากคุณมีข้อกำหนดที่รัดกุมเป็นพิเศษ จะเป็นการดีกว่าหากจัดให้มีการทดสอบแบบเดียวกับที่โครงการ Hermitage ทำ

5.3 "I" และตัวอักษรอื่นในกรด

การแยกตัวเป็นสิ่งที่ผู้คนหมายถึงเมื่อพวกเขาพูดถึงกรดโดยทั่วไป และด้วยเหตุนี้ฉันจึงเริ่มวิเคราะห์ตัวย่อนี้ด้วยความโดดเดี่ยวและไม่ได้เป็นไปตามลำดับดังที่ผู้ที่พยายามอธิบายแนวคิดนี้มักจะทำ ทีนี้มาดูตัวอักษรอีกสามตัวที่เหลือกัน

จำตัวอย่างของเราอีกครั้งด้วยการโอนเงินผ่านธนาคาร ธุรกรรมเพื่อโอนเงินจากบัญชีหนึ่งไปยังอีกบัญชีหนึ่งรวมถึงการดำเนินการถอนเงินจากบัญชีแรกและการดำเนินการเติมเต็มในบัญชีที่สอง หากการเติมเต็มของบัญชีที่สองล้มเหลว คุณอาจไม่ต้องการให้ดำเนินการถอนจากบัญชีแรกเกิดขึ้น กล่าวอีกนัยหนึ่งคือการทำธุรกรรมสำเร็จอย่างสมบูรณ์หรือไม่เกิดขึ้นเลย แต่ก็ไม่สามารถทำได้เพียงบางส่วนเท่านั้น คุณสมบัตินี้เรียกว่า "ปรมาณู" และเป็น "A" ในกรด

เมื่อธุรกรรมของเราถูกดำเนินการ เช่นเดียวกับการดำเนินการอื่นๆ ก็จะมีการถ่ายโอนฐานข้อมูลจากสถานะที่ถูกต้องไปยังอีกสถานะหนึ่ง ฐานข้อมูลบางแห่งมีสิ่งที่เรียกว่าข้อจำกัดนั่นคือกฎที่ใช้กับข้อมูลที่เก็บไว้ เช่น เกี่ยวกับคีย์หลักหรือรอง ดัชนี ค่าดีฟอลต์ ประเภทคอลัมน์ เป็นต้น ดังนั้นในการทำธุรกรรมเราต้องแน่ใจว่าจะปฏิบัติตามข้อจำกัด เหล่านี้ทั้งหมด

การรับประกันนี้เรียกว่า "ความสอดคล้อง" และตัวอักษรCเป็นกรด (อย่าสับสนกับความสม่ำเสมอจากโลกของแอปพลิเคชันแบบกระจาย ซึ่งเราจะพูดถึงในภายหลัง) ฉันจะยกตัวอย่างที่ชัดเจนสำหรับความสอดคล้องในแง่ของกรด: แอปพลิเคชันสำหรับร้านค้าออนไลน์ต้องการเพิ่มordersแถวในตารางและIDจากตารางproduct_idจะถูกระบุ ในคอลัมน์ - ทั่วไป.productsforeign key

หากผลิตภัณฑ์ถูกลบออกจากการจัดประเภทและตามด้วยฐานข้อมูล การดำเนินการแทรกแถวไม่ควรเกิดขึ้น และเราจะได้รับข้อผิดพลาด การรับประกันนี้เมื่อเทียบกับการรับประกันอื่น ๆ นั้นค่อนข้างไกลในความคิดของฉัน - หากเพียงเพราะการใช้ข้อ จำกัดจากฐานข้อมูลอย่างแข็งขันหมายถึงการเปลี่ยนความรับผิดชอบสำหรับข้อมูล (เช่นเดียวกับการเปลี่ยนแปลงตรรกะทางธุรกิจบางส่วนหากเรากำลังพูดถึง ข้อ จำกัด เช่น CHECK ) จากแอปพลิเคชันไปยังฐานข้อมูลซึ่งตามที่พวกเขาพูดตอนนี้เป็นเช่นนั้น

และในที่สุดก็ยังคงอยู่D- "ความต้านทาน" (ความทนทาน) ความล้มเหลวของระบบหรือความล้มเหลวอื่นๆ ไม่ควรนำไปสู่การสูญเสียผลลัพธ์ของธุรกรรมหรือเนื้อหาฐานข้อมูล นั่นคือหากฐานข้อมูลตอบกลับว่าการทำธุรกรรมสำเร็จนั่นหมายความว่าข้อมูลนั้นถูกบันทึกไว้ในหน่วยความจำไม่ลบเลือน - ตัวอย่างเช่นในฮาร์ดดิสก์ อย่างไรก็ตาม นี่ไม่ได้หมายความว่าคุณจะเห็นข้อมูลทันทีในคำขออ่านครั้งต่อไป

เมื่อวันก่อน ฉันทำงานกับ DynamoDB จาก AWS (Amazon Web Services) และส่งข้อมูลบางส่วนเพื่อบันทึก และหลังจากได้รับคำตอบHTTP 200(ตกลง) หรืออะไรทำนองนั้น ฉันตัดสินใจตรวจสอบ - และไม่เห็นสิ่งนี้ ข้อมูลในฐานข้อมูลเป็นเวลา 10 วินาทีถัดไป นั่นคือ DynamoDB ยอมรับข้อมูลของฉัน แต่ไม่ใช่ทุกโหนดที่ซิงโครไนซ์ทันทีเพื่อรับสำเนาข้อมูลล่าสุด (แม้ว่าอาจอยู่ในแคชก็ตาม) ที่นี่เราปีนขึ้นไปในอาณาเขตของความสอดคล้องกันอีกครั้งในบริบทของระบบกระจาย แต่เวลาที่จะพูดถึงมันยังมาไม่ถึง

ตอนนี้เรารู้แล้วว่าการรับประกันของกรดคืออะไร และเรารู้ด้วยซ้ำว่าทำไมมันถึงมีประโยชน์ แต่เราจำเป็นต้องมีในทุกแอปพลิเคชันหรือไม่? และถ้าไม่เมื่อไหร่? DB ทั้งหมดเสนอการรับประกันเหล่านี้หรือไม่ และหากไม่มี พวกเขาจะเสนออะไรแทน