ดังที่ brb tea กล่าวขึ้นอยู่กับการใช้งานฐานข้อมูลและอัลกอริทึมที่ใช้: MVCC หรือ Two Phase Locking
CUBRID (โอเพ่นซอร์ส RDBMS) อธิบายแนวคิดของอัลกอริทึมทั้งสองนี้:
รายการแรกคือเมื่อธุรกรรม T2 พยายามเปลี่ยนระเบียน A จะรู้ว่าธุรกรรม T1 ได้เปลี่ยนระเบียน A แล้วและรอจนกว่าธุรกรรม T1 จะเสร็จสมบูรณ์เนื่องจากธุรกรรม T2 ไม่สามารถทราบได้ว่าธุรกรรม T1 จะถูกผูกมัดหรือรีด กลับ. วิธีนี้เรียกว่าการล็อคสองเฟส (2PL)
- การควบคุมการทำงานพร้อมกันหลายเวอร์ชัน (MVCC)
อีกวิธีหนึ่งคืออนุญาตให้แต่ละธุรกรรม T1 และ T2 มีเวอร์ชันที่เปลี่ยนแปลงของตนเอง แม้ว่าธุรกรรม T1 จะเปลี่ยนเร็กคอร์ด A จาก 1 เป็น 2 ทรานแซคชัน T1 จะทิ้งค่าเดิม 1 ตามที่เป็นอยู่และเขียนว่าเวอร์ชันธุรกรรม T1 ของเร็กคอร์ด A คือ 2 จากนั้นธุรกรรม T2 ต่อไปนี้จะเปลี่ยนเร็กคอร์ด A จาก 1 ถึง 3 ไม่ใช่ตั้งแต่ 2 ถึง 4 และเขียนว่าเวอร์ชันธุรกรรม T2 ของเร็กคอร์ด A คือ 3
เมื่อทรานแซคชัน T1 ถูกย้อนกลับไม่สำคัญว่า 2 เวอร์ชันธุรกรรม T1 จะไม่ถูกนำไปใช้กับเรกคอร์ด A หลังจากนั้นหากมีการคอมมิตธุรกรรม T2 3 ซึ่งเป็นเวอร์ชันธุรกรรม T2 จะถูกนำไปใช้กับเรกคอร์ด A หากมีการทำธุรกรรม T1 ก่อนการทำธุรกรรม T2 ระเบียน A จะเปลี่ยนเป็น 2 และจากนั้นเป็น 3 ในขณะที่ทำธุรกรรม T2 สถานะฐานข้อมูลขั้นสุดท้ายจะเหมือนกับสถานะของการดำเนินการแต่ละธุรกรรมโดยอิสระโดยไม่มีผลกระทบต่อธุรกรรมอื่น ๆ ดังนั้นจึงเป็นไปตามคุณสมบัติของกรด วิธีนี้เรียกว่า Multi-version concurrency control (MVCC)
MVCC อนุญาตให้ทำการแก้ไขพร้อมกันโดยมีค่าใช้จ่ายเพิ่มขึ้นในหน่วยความจำ (เนื่องจากต้องรักษาเวอร์ชันต่างๆของข้อมูลเดียวกัน) และการคำนวณ (ในระดับ REPETEABLE_READ คุณจะไม่สามารถอัปเดตหลวมได้ดังนั้นจึงต้องตรวจสอบเวอร์ชันของข้อมูลเช่น Hiberate ทำกับOptimistick Locking )
ในระดับการแยกธุรกรรม 2PL ควบคุมสิ่งต่อไปนี้ :
มีการล็อกเมื่ออ่านข้อมูลหรือไม่และมีการร้องขอการล็อกประเภทใด
ล็อคการอ่านจะเก็บไว้นานแค่ไหน
การดำเนินการอ่านที่อ้างถึงแถวที่แก้ไขโดยธุรกรรมอื่นหรือไม่:
บล็อกจนกว่าการล็อกพิเศษในแถวจะถูกปลดปล่อย
ดึงข้อมูลเวอร์ชันที่มุ่งมั่นของแถวที่มีอยู่ในขณะที่คำสั่งหรือธุรกรรมเริ่มต้น
อ่านการแก้ไขข้อมูลที่ไม่ได้ผูกมัด
การเลือกระดับการแยกธุรกรรมไม่มีผลต่อการล็อกที่ได้มาเพื่อป้องกันการแก้ไขข้อมูล ธุรกรรมจะได้รับการล็อกเฉพาะสำหรับข้อมูลใด ๆ ที่ปรับเปลี่ยนและเก็บล็อกนั้นไว้จนกว่าธุรกรรมจะเสร็จสมบูรณ์โดยไม่คำนึงถึงระดับการแยกที่กำหนดไว้สำหรับธุรกรรมนั้น สำหรับการดำเนินการอ่านระดับการแยกธุรกรรมส่วนใหญ่กำหนดระดับการป้องกันจากผลกระทบของการแก้ไขที่ทำโดยธุรกรรมอื่น ๆ
ระดับการแยกที่ต่ำลงจะเพิ่มความสามารถของผู้ใช้หลายคนในการเข้าถึงข้อมูลในเวลาเดียวกัน แต่จะเพิ่มจำนวนเอฟเฟกต์พร้อมกันเช่นการอ่านสกปรกหรือการอัปเดตที่สูญหายซึ่งผู้ใช้อาจพบ
ตัวอย่างที่เป็นรูปธรรมของความสัมพันธ์ระหว่างการล็อกและระดับการแยกในSQL Server (ใช้ 2PL ยกเว้นบน READ_COMMITED กับ READ_COMMITTED_SNAPSHOT = ON)
READ_UNCOMMITED: อย่าออกการล็อกที่ใช้ร่วมกันเพื่อป้องกันไม่ให้ธุรกรรมอื่นแก้ไขข้อมูลที่อ่านโดยธุรกรรมปัจจุบัน READ UNCOMMITTED ธุรกรรมจะไม่ถูกปิดกั้นโดยการล็อกพิเศษที่จะป้องกันไม่ให้ธุรกรรมปัจจุบันอ่านแถวที่ได้รับการแก้ไข แต่ไม่ได้กระทำโดยธุรกรรมอื่น [... ]
READ_COMMITED:
- ถ้า READ_COMMITTED_SNAPSHOT ถูกตั้งค่าเป็น OFF (ค่าเริ่มต้น): ใช้การล็อกที่ใช้ร่วมกันเพื่อป้องกันไม่ให้ธุรกรรมอื่นแก้ไขแถวในขณะที่ธุรกรรมปัจจุบันกำลังดำเนินการอ่าน การล็อกที่ใช้ร่วมกันยังบล็อกคำสั่งไม่ให้อ่านแถวที่แก้ไขโดยธุรกรรมอื่นจนกว่าธุรกรรมอื่นจะเสร็จสมบูรณ์ [... ] การล็อกแถวจะถูกปลดก่อนที่จะประมวลผลแถวถัดไป [... ]
- ถ้า READ_COMMITTED_SNAPSHOT ถูกตั้งค่าเป็นเปิดโปรแกรมฐานข้อมูลจะใช้การกำหนดเวอร์ชันของแถวเพื่อนำเสนอแต่ละคำสั่งที่มีสแน็ปช็อตของข้อมูลที่สอดคล้องกันตามธุรกรรมที่มีอยู่ในตอนเริ่มต้นของคำสั่ง ไม่ได้ใช้การล็อกเพื่อป้องกันข้อมูลจากการอัปเดตโดยธุรกรรมอื่น ๆ
REPETEABLE_READ: การล็อกที่ใช้ร่วมกันจะถูกวางไว้บนข้อมูลทั้งหมดที่อ่านโดยแต่ละคำสั่งในธุรกรรมและจะเก็บไว้จนกว่าธุรกรรมจะเสร็จสมบูรณ์
SERIALIZABLE: การล็อกช่วงจะอยู่ในช่วงของค่าคีย์ที่ตรงกับเงื่อนไขการค้นหาของแต่ละคำสั่งที่ดำเนินการในธุรกรรม [... ] การล็อกช่วงจะถูกระงับจนกว่าธุรกรรมจะเสร็จสมบูรณ์