การมองโลกในแง่ดีกับการมองโลกในแง่ร้าย


571

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

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

แต่เพียงเพื่อตรวจสอบในแง่ดีหมายถึง "ไม่ล็อคตารางในขณะที่อ่าน" และมองโลกในแง่ร้ายหมายถึง "ล็อคตารางในขณะที่อ่าน"



1
นั่นเป็นคำถามที่ดีโดยเฉพาะอย่างยิ่งเพราะในserializabilityAt any technique type conflicts should be detected and considered, with similar overhead for both materialized and non-materialized conflictsฉันอ่าน
Little Alien

1
ที่นี่คุณสามารถหาคำอธิบายที่ดีที่นี่ใน SO เกี่ยวกับสิ่งที่เป็นแนวคิดที่รากของล็อคในแง่ดี
Diego Mazzaro

คำตอบ:


812

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

หากบันทึกสกปรก (เช่นรุ่นที่แตกต่างกับของคุณ) คุณยกเลิกการทำธุรกรรมและผู้ใช้สามารถเริ่มต้นใหม่ได้

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

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

ในกรณีหลังคุณเปิดการทำธุรกรรมด้วย TxID จากนั้นเชื่อมต่ออีกครั้งโดยใช้ ID นั้น DBMS รักษาล็อคและช่วยให้คุณสามารถเลือกเซสชันสำรองผ่าน TxID นี่คือวิธีการกระจายการทำธุรกรรมโดยใช้โปรโตคอลการส่งสองเฟส (เช่นXAหรือCOM + ธุรกรรม )


148
การล็อคในแง่ดีไม่จำเป็นต้องใช้หมายเลขรุ่น กลยุทธ์อื่น ๆ ได้แก่ การใช้ (a) การประทับเวลาหรือ (b) สถานะทั้งหมดของแถวเอง กลยุทธ์หลังน่าเกลียด แต่หลีกเลี่ยงความต้องการคอลัมน์รุ่นเฉพาะในกรณีที่คุณไม่สามารถแก้ไขสคีมาได้
Andrew Swan

2
@geek - โพรโทคอลการทำธุรกรรมแบบกระจายเช่น XA อนุญาตให้ตัวระบุการทำธุรกรรมแยกต่างหากได้รับการ reticulated รอบหนึ่งระบบขึ้นไป โปรโตคอลประเภทนี้อนุญาตให้ใช้ล็อคได้ผ่านการเชื่อมต่อที่มีพูลเนื่องจากตัวระบุธุรกรรมไม่ได้ถูกนำมารวมกันจากเซสชันและระบุอย่างชัดเจน อย่างไรก็ตามสิ่งนี้มีค่าใช้จ่ายเกิดขึ้นและมีแนวโน้มที่จะเกิดการล็อคและตัวระบุธุรกรรมหากแอปพลิเคชันของคุณไม่ละเอียดเกี่ยวกับการติดตามพวกเขา มันเป็นวิธีการแก้ปัญหาเฮฟวี่เวทมากขึ้น
เกี่ยวข้องกับ

22
@supercat - อย่ายอมรับว่าการล็อคในแง่ดีนั้นมีความแม่นยำน้อยกว่า 100% - ตราบใดที่มันตรวจสอบบันทึกการป้อนข้อมูลทั้งหมดสำหรับการทำธุรกรรมที่ควรจะไม่ได้แก้ไขในช่วงเวลานั้นมันแม่นยำเท่ากับล็อคในแง่ร้าย บันทึกเดียวกัน ข้อแตกต่างที่สำคัญคือการล็อกในแง่ดีจะเกิดค่าใช้จ่ายเฉพาะในกรณีที่มีข้อขัดแย้งในขณะที่การล็อกในแง่ร้ายจะช่วยลดค่าใช้จ่ายในการขัดแย้ง ดังนั้นแง่ดีที่สุดดีที่สุดในกรณีที่การทำธุรกรรมส่วนใหญ่ไม่ขัดแย้ง - ซึ่งฉันหวังว่าโดยปกติแล้วจะเป็นกรณีสำหรับแอปส่วนใหญ่
RichVel

2
@Legends - การใช้การล็อค optimsitic แน่นอนจะเป็นกลยุทธ์ที่เหมาะสมสำหรับโปรแกรมประยุกต์บนเว็บ
เกี่ยวข้องกับ OfTunbridgeWells

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

177

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

การล็อคในแง่ร้ายถูกใช้เมื่อคาดว่าจะมีการชนกัน ธุรกรรมที่จะละเมิดการซิงโครไนซ์ถูกบล็อกเพียง

ในการเลือกกลไกการล็อคที่เหมาะสมคุณจะต้องประเมินจำนวนการอ่านและการเขียนและวางแผนตามความเหมาะสม


ในกรณีปกติคำสั่งนั้นสมบูรณ์แบบ แต่ในกรณีพิเศษที่คุณสามารถจัดการการดำเนินการCAS ที่ไม่ถูกต้องตามที่ @skaffman พูดถึงในคำตอบฉันจะบอกว่ามันขึ้นอยู่กับ
ได้ยิน

75

ในแง่ดีสมมติว่าไม่มีอะไรเปลี่ยนแปลงในขณะที่คุณกำลังอ่าน

ในแง่ร้ายสมมติว่ามีบางสิ่งที่จะทำให้ล็อค

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

เว็บแอปพลิเคชั่นส่วนใหญ่ใช้ได้ดีกับการอ่านที่สกปรก - ในบางครั้งข้อมูลจะไม่ได้รับการโหลดซ้ำครั้งต่อไป

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

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


JPA Optimistic Locking ช่วยให้คุณรับประกันความสอดคล้องในการอ่าน
Gili

4
ความสอดคล้องในการอ่านเป็นข้อกังวลแยกต่างหาก - ด้วย PostgreSQL, Oracle และฐานข้อมูลอื่น ๆ คุณจะได้รับมุมมองข้อมูลที่สอดคล้องกันไม่ว่าจะมีการอัพเดตใด ๆ ที่ยังไม่ได้รับการยอมรับ
RichVel

ฉันต้องเห็นด้วยกับ @RichVel ในอีกด้านหนึ่งฉันสามารถดูว่าการล็อกในแง่ร้ายสามารถป้องกันการอ่านที่สกปรกได้อย่างไรหากระดับการแยกธุรกรรมของคุณไม่ได้รับการอ่าน แต่มันก็เป็นความเข้าใจผิดที่จะบอกว่าการล็อคในแง่ดีมีความไวต่อการอ่านสกปรกโดยไม่พูดถึงว่าฐานข้อมูลส่วนใหญ่ (รวมถึง MS SQL Server) มีระดับการแยกเริ่มต้นของ "READ COMMITTED" ซึ่งป้องกันการอ่านสกปรก ในแง่ร้าย
antinome

Eric Brower กล่าวว่านายธนาคารที่ชอบปฏิบัติการสกปรก ปรมาจารย์ของคุณดูจะออกจากรถเข็นอย่างแน่นอน
Little Alien

1
เอริคบรูเออร์เป็นกูรูที่ให้ทฤษฎีบทหมวกกล่าวว่าเกี่ยวกับความมั่นคงในกลุ่มธนาคาร มันตรงกันข้ามกับสิ่งที่คุณให้เกียรติ
Little Alien

50

นอกจากสิ่งที่พูดไปแล้ว:

  • มันควรจะกล่าวว่าการoptimisticล็อคมีแนวโน้มที่จะปรับปรุงการทำงานพร้อมกันที่ค่าใช้จ่ายของการคาดการณ์
  • Pessimisticการล็อคมีแนวโน้มที่จะลดการทำงานพร้อมกัน แต่สามารถคาดเดาได้มากขึ้น คุณจ่ายเงิน ฯลฯ

3
ฉันไม่เห็นว่าการคาดการณ์ (แต่คุณกำหนดไว้) นั้นได้รับการปรับปรุงด้วยการล็อคในแง่ร้าย - ถ้าคุณหมายถึง 'การทำธุรกรรมสามารถทำให้เสร็จสมบูรณ์ได้เมื่อล็อคถูกต้อง' คุณถูกต้อง แต่จนกระทั่งธุรกรรมมีล็อคที่ต้องการทั้งหมด ล็อคที่เหลืออยู่และในความเป็นจริงอาจถูกยกเลิกเนื่องจากการตรวจจับการหยุดชะงักของ DB + ตรรกะความละเอียด แอปที่ใช้การล็อกในแง่ร้ายอาจมีเวลาดำเนินการที่คาดเดาไม่ได้สูงตัวอย่างคลาสสิกคือมีคนล็อกเร็กคอร์ด X จากนั้นไปทานอาหารกลางวันจากนั้นผู้ใช้ล็อกเร็กคอร์ด X และ Y จากนั้นอีก Y และ Z เป็นต้น ..
RichVel

40

เมื่อจัดการกับความขัดแย้งคุณมีสองตัวเลือก:

  • คุณสามารถพยายามหลีกเลี่ยงความขัดแย้งและนั่นคือสิ่งที่การมองโลกในแง่ร้ายทำ
  • หรือคุณอาจยอมให้มีความขัดแย้งเกิดขึ้น แต่คุณต้องตรวจสอบเมื่อทำธุรกรรมของคุณและนั่นคือสิ่งที่ Optimistic Locking ทำ

ตอนนี้มาลองพิจารณาความผิดปกติที่หายไปของ Updateต่อไปนี้:

ปรับปรุงหายไป

ความผิดปกติที่หายไปของการอัปเดตสามารถเกิดขึ้นได้ในระดับการแยกแบบมุ่งมั่นที่อ่านแล้ว

ในแผนภาพด้านบนเราจะเห็นว่าอลิซเชื่อว่าเธอสามารถถอนได้ 40 จากเธอaccountแต่ไม่ทราบว่าบ็อบเพิ่งเปลี่ยนยอดเงินในบัญชีและตอนนี้เหลือเพียง 20 บัญชีในบัญชีนี้

การล็อคในแง่ร้าย

การล็อคในแง่ร้ายบรรลุเป้าหมายนี้โดยการแชร์หรือล็อกการอ่านในบัญชีเพื่อป้องกันไม่ให้บ็อบเปลี่ยนบัญชี

การอัปเดตการมองโลกแง่ร้ายสูญหาย

ในแผนภาพด้านบนทั้งอลิซและบ็อบจะได้รับล็อกการอ่านในaccountแถวของตารางที่ผู้ใช้ทั้งสองได้อ่าน ฐานข้อมูลได้รับการล็อคเหล่านี้บน SQL Server เมื่อใช้ Repeatable Read หรือ Serializable

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

หลังจากที่อลิซได้ทำธุรกรรมของเธอแล้วและล็อคการอ่านได้เปิดตัวในaccountแถวนั้นบ๊อบUPDATEจะกลับมาทำงานต่อและใช้การเปลี่ยนแปลงนั้น จนกว่าอลิซจะปลดล็อคการอ่านบล็อกของ UPDATE ของบ็อบ

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

การล็อคในแง่ดี

การล็อกในแง่ดีช่วยให้เกิดความขัดแย้ง แต่ตรวจพบเมื่อใช้ UPDATE ของอลิซเมื่อมีการเปลี่ยนแปลงเวอร์ชัน

ธุรกรรมระดับแอปพลิเคชัน

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

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการเข้าถึงข้อมูลกรอบการดำเนินการล็อคในแง่ดี, ตรวจสอบบทความนี้

ธุรกรรมระดับแอปพลิเคชัน

ระบบฐานข้อมูลเชิงสัมพันธ์ได้เกิดขึ้นในช่วงปลายยุค 70 ต้นยุค 70 เมื่อลูกค้าต้องการเชื่อมต่อกับเมนเฟรมผ่านเทอร์มินัล นั่นเป็นเหตุผลที่เรายังคงเห็นระบบฐานข้อมูลกำหนดเงื่อนไขเช่นการตั้งค่า SESSION

ทุกวันนี้บนอินเทอร์เน็ตเราจะไม่ทำการอ่านและเขียนอีกต่อไปในบริบทของธุรกรรมฐานข้อมูลเดียวกันและ ACID นั้นไม่เพียงพออีกต่อไป

ตัวอย่างเช่นพิจารณากรณีการใช้งานต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

หากไม่มีการล็อกในแง่ดีจะไม่มีทางที่ Lost Update นี้จะถูกตรวจจับแม้ว่าธุรกรรมฐานข้อมูลจะใช้ Serializable นี่เป็นเพราะการอ่านและเขียนถูกดำเนินการในคำขอ HTTP ที่แยกต่างหากดังนั้นในธุรกรรมฐานข้อมูลที่แตกต่างกัน

ดังนั้นการล็อกในแง่ดีสามารถช่วยคุณป้องกันการอัพเดทที่หายไปได้แม้ว่าจะใช้ธุรกรรมระดับแอปพลิเคชันที่รวมเวลาที่ผู้ใช้คิดเช่นกัน

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการสมัครระดับการทำธุรกรรมหรือตรรกะตรวจสอบบทความนี้

ข้อสรุป

การล็อก Optimistic เป็นเทคนิคที่มีประโยชน์มากและใช้งานได้ดีแม้ว่าจะใช้ระดับการแยกที่เข้มงวดน้อยกว่าเช่น Read Committed หรือเมื่อการอ่านและเขียนถูกเรียกใช้งานในฐานข้อมูลที่ตามมา

ข้อเสียของการล็อคในแง่ดีคือการย้อนกลับจะถูกทริกเกอร์โดยกรอบการเข้าถึงข้อมูลเมื่อมีการจับOptimisticLockExceptionดังนั้นจึงสูญเสียงานทั้งหมดที่เราเคยทำก่อนหน้านี้โดยการทำธุรกรรมการดำเนินการในปัจจุบัน

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

ด้วยเหตุนี้การล็อคในแง่ร้ายอาจเหมาะสมกับแร่เมื่อเกิดความขัดแย้งเกิดขึ้นบ่อยครั้งเนื่องจากช่วยลดโอกาสในการทำธุรกรรมย้อนกลับ


คุณต้องการแนะนำสถานการณ์ใดให้เลือก OptimisticLocking และ PessimisticLocking มันขึ้นอยู่กับว่า OptimisticLockException เกิดขึ้นบ่อยแค่ไหน?
Stimpson Cat

1
มันขึ้นอยู่กับกรณีการใช้งาน บางครั้งการล็อกในแง่ดีเป็นวิธีแก้ปัญหาเท่านั้น (เช่นธุรกรรมที่มีหลายคำขอ) ในบางครั้งการล็อคในแง่ร้ายเป็นทางแก้ปัญหาเดียว (เช่นการล็อกคำแนะนำของ PostgreSQL ) บางครั้งคุณต้องรวมมันเข้าด้วยPESSIMISTIC_FORCE_INCREMENTกัน
Vlad Mihalcea

22

ฉันคิดว่าอีกหนึ่งกรณีเมื่อการล็อกในแง่ร้ายจะเป็นทางเลือกที่ดีกว่า

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


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

คำอธิบายที่ดีให้คุณลงคะแนนจากฉัน
Dulaj Kulathunga

15

โดยทั่วไปมีสองคำตอบที่ได้รับความนิยมมากที่สุด แรกโดยทั่วไปว่า

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

คำตอบก็คือ

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

หรือ

การล็อคในแง่ดีจะทำงานได้ดีที่สุดเมื่อคุณมีการชนที่หายาก

ตามที่วางไว้บนหน้านี้

ฉันสร้างคำตอบเพื่ออธิบายว่า "รักษาการเชื่อมต่อ" เกี่ยวข้องกับ "การชนกันน้อย" อย่างไร

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

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

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

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

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


12

ในกรณีส่วนใหญ่การล็อคในแง่ดีนั้นมีประสิทธิภาพมากกว่าและให้ประสิทธิภาพที่สูงกว่า เมื่อเลือกระหว่างการล็อกในแง่ร้ายและการมองโลกในแง่ดีให้พิจารณาสิ่งต่อไปนี้:

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

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

  • การล็อกในแง่ดีมีประโยชน์หากความเป็นไปได้ของความขัดแย้งต่ำมาก - มีเร็กคอร์ดจำนวนมาก แต่มีผู้ใช้ค่อนข้างน้อยหรือมีการอัพเดตน้อยมากและการดำเนินการอ่านเป็นส่วนใหญ่


3

กรณีการใช้งานหนึ่งกรณีสำหรับการล็อกในแง่ดีคือให้แอปพลิเคชันของคุณใช้ฐานข้อมูลเพื่ออนุญาตให้หนึ่งในเธรด / โฮสต์ของคุณ 'เรียกร้อง' งาน นี่เป็นเทคนิคที่มีประโยชน์สำหรับฉันเป็นประจำ

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

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


3

มีการพูดถึงสิ่งดี ๆ มากมายเกี่ยวกับการมองโลกในแง่ดีและการมองโลกในแง่ร้าย จุดสำคัญหนึ่งที่ควรพิจารณามีดังนี้:

เมื่อใช้การล็อกในแง่ดีเราต้องระมัดระวังความจริงที่ว่าแอปพลิเคชันจะกู้คืนอย่างไรจากความล้มเหลวเหล่านี้

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

สถานการณ์ความล้มเหลวจำเป็นต้องได้รับการพิจารณา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.