เหตุใดการล็อกในแง่ดีจึงเร็วกว่าการล็อกในแง่ร้าย


9

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

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


5
คำอธิบายสั้น ๆ มีอยู่ในการตั้งชื่อ การล็อคในแง่ดีจะทำงานได้ดีเมื่อโอกาสของการล็อคที่ขัดแย้งกันอยู่ในระดับต่ำ เรามองโลกในแง่ดีเกี่ยวกับปฏิสัมพันธ์ของกระบวนการหลาย ๆ กระบวนการ การล็อคในแง่ร้ายจะทำงานได้ดีเมื่อโอกาสของการล็อคที่ขัดแย้งกันสูง เรามองโลกในแง่ร้ายเกี่ยวกับปฏิสัมพันธ์ของกระบวนการหลาย ๆ กระบวนการ ทั้งสองจะดำเนินการย่อยอย่างเหมาะสมในกรณีที่ตรงข้ามของพวกเขาเหมาะสมกว่า
Mark Storey-Smith

การล็อคในแง่ดีอาจหรือไม่เร็วกว่าการล็อคในแง่ร้ายขึ้นอยู่กับปริมาณงานของคุณ
AK

คำตอบ:


8

คำถามซ้ำจาก:

/programming/129329/optimistic-vs-pessimistic-locking

คัดลอก / วางคำตอบจากลิงค์ด้านบน:

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

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

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

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

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

แก้ไข (การเพิ่มข้อมูลเพิ่มเติมเพื่อตอบคำถามเรื่องประสิทธิภาพ):

ประสิทธิภาพฉลาดขึ้นอยู่กับสภาพแวดล้อมของคุณ พิจารณาปัจจัยต่อไปนี้ในการตัดสินใจ:

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

ตัวอย่างเช่นด้วย MS SQL Server จะถูกย้ายไปยัง TempDB และบางสิ่งระหว่าง 12-14 ไบต์จะถูกต่อท้ายที่ท้ายคอลัมน์ การเปิดการล็อกในแง่ดีด้วยระดับการแยกเช่น Snapshot Isolation อาจทำให้เกิดการแตกแฟรกเมนต์และปัจจัยการเติมของคุณจะต้องได้รับการปรับเนื่องจากแถวตอนนี้มีข้อมูลเพิ่มเติมในตอนท้ายซึ่งอาจทำให้หน้าใกล้เต็มเพื่อทำให้เกิดการแยกหน้า ประสิทธิภาพของคุณ หาก TempDB ของคุณอยู่ภายใต้การปรับให้เหมาะสมสิ่งนี้จะไม่เร็วอย่างที่คิด

ดังนั้นฉันคิดว่ารายการตรวจสอบคือ:

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

นี่คือความคิดของฉันในเรื่องนี้เปิดรับฟังมากขึ้นจากชุมชน


ขอบคุณ @Ali Razeghi (+1) - ฉันคิดว่า dba.se เป็นสถานที่ที่เหมาะสมกว่าสำหรับคำถามนี้ นอกจากนี้แม้ว่านี่จะเป็นคำตอบที่ยอดเยี่ยม แต่ก็ไม่ได้ตอบคำถามประสิทธิภาพของฉัน (เมื่อหนึ่งเร็วกว่าอีก) ขอบคุณอีกครั้ง!
Mara

สวัสดีมารนั่นเป็นจุดที่ดี ฉันได้ขยายคำตอบ ขอบคุณ
Ali Razeghi

11

คุณเข้าใจผิดว่าการล็อคในแง่ดี

การล็อกในแง่ดีไม่ทำให้การทำธุรกรรมรอกัน

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


1

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

ด้วยกลยุทธ์การล็อคในแง่ดีการ 'แฮงค์' จะเกิดขึ้นในฝั่งไคลเอ็นต์และไม่ส่งผลกระทบต่อผู้อื่น

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

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


จุดที่น่าสนใจ a1ex07 การล็อก optimsitic ยังรวมถึงการล็อค แต่เนื่องจากการเขียนจะบล็อกการเขียนอื่น ๆ ถูกต้องหรือไม่
Ali Razeghi

ไม่มันไม่ นั่นเป็นเหตุผลที่มัน "เร็ว"
เออร์วิน Smout

นั่นอาจเป็นกรณีของ Oracle แต่สำหรับ MS SQL Server เนื่องจากใช้ระดับการแยกแบบ 'read commit' โดยค่าเริ่มต้นการล็อกในแง่ดีจะทำให้ผู้อ่านและเธรดตัวเขียนทำงานได้พร้อมกัน แต่การเขียนจะบล็อกการเขียนจนกว่าจะเสร็จสิ้น
Ali Razeghi

@ Ali Razeghi: ฉันไม่แน่ใจว่าฉันทำตามจุดของคุณ ใน SQLServer ที่มีตัวอ่านที่อ่านแล้วจะบล็อกผู้อ่านตามค่าเริ่มต้นเว้นแต่จะมีการเปิด "READ_COMMITTED_SNAPSHOT" การล็อกในแง่ดีไม่ใช่การล็อคกับทรัพยากร db (แถว / หน้า / ตาราง) แต่เป็นข้อตกลงบางอย่างระหว่างแอปพลิเคชันทั้งหมดที่ใช้ฐานข้อมูลเพื่อไม่อัปเดตระเบียนหากรุ่นไม่ตรงกับที่คาดไว้
a1ex07

1
@Eamon Nerbonne: ฉันพูดเกี่ยวกับ 'นักเขียนไม่บล็อกผู้อ่าน' ... คุณเห็นฉันพูดถึงอะไรเกี่ยวกับ "นักเขียนบล็อก / ไม่บล็อกนักเขียน"?
a1ex07

0

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

การล็อกในแง่ร้ายถือว่าการทำธุรกรรมที่เกิดขึ้นพร้อมกันจะขัดแย้งกันดังนั้นจึงต้องใช้การล็อกมันทำโดยการระบุระดับ ISOLATION (อ่าน Uncommitted, Read Committed, Repeatable Read และ Serializable) ของการจัดการทรานแซคชัน ล็อคทำหน้าที่ในการปกป้องทรัพยากรหรือวัตถุที่ใช้ร่วมกัน (ตาราง, แถวข้อมูล, บล็อคข้อมูล, รายการที่แคช, การเชื่อมต่อและระบบทั้งหมด) เรามีการล็อคหลายประเภทเช่นการล็อคที่ใช้ร่วมกัน, ล็อคการปรับปรุง, ล็อคสิ่งที่ใส่เข้าไป, ล็อคพิเศษ, ล็อคธุรกรรม, ล็อค DML, ล็อคสคีมาและล็อคการกู้คืนการสำรองข้อมูล

เพื่อรับแนวคิดเพิ่มเติม


-3

มันผิดที่จะบอกว่าการล็อคในแง่ร้ายนั้นช้ากว่าการมองโลกในแง่ดีหรือบอกว่าแง่ดีเร็วกว่า หนึ่งแบบสอบถามคลาสสิกเพื่อแสดงให้เห็นถึงวิธีคิดที่ไม่เหมาะสมนี้คือการรวมกันใน RDBMS ที่แตกต่างกันเช่น:

SELECT COUNT(*) FROM atable

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

เช่นบนพีซีของฉันข้อความค้นหาเดียวกันใช้เวลา 27 ms บน SQL Server และ 109 ใน PostGreSQL ...

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


4
วิธีการควบคุมการทำงานพร้อมกันของ DBMS เป็นมุมฉากกับการล็อกในแง่ดี / มองโลกในแง่ร้ายและการเปรียบเทียบเวลาเรียกใช้แบบสอบถามในสอง DBMS ที่แตกต่างกันนั้นทำให้เข้าใจผิด
mustaccio

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