คุณจะทดสอบเงื่อนไขการแข่งขันในฐานข้อมูลได้อย่างไร


30

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

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

หมายเหตุ: ฉันใช้ PostgreSQL และ Perl ดังนั้นหากไม่สามารถตอบได้โดยทั่ว ๆ ไปก็น่าจะได้รับการติดซ้ำเช่นนี้

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


โดย "race race" คุณหมายถึง "deadlock" หรือไม่
ออกุส

2
@Gaius ... ไม่ แต่ฉันเชื่อว่าเป็นผลมาจากสภาพการแข่งขันบางอย่าง
xenoterracide

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

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

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

คำตอบ:


11

ฉันทำมันตลอดเวลากับโมดูล T-SQL ของฉัน

โดยพื้นฐานแล้วสิ่งที่คุณต้องทำคือการเรียกใช้โมดูลของคุณจากสองคนหรือมากกว่าการเชื่อมต่อในวงสำหรับไม่กี่นาที โดยทั่วไปปัญหาที่อาจเกิดขึ้นทั้งหมดจะปรากฏในไม่กี่นาทีสมมติว่าคุณมีกล่อง SQL Server ที่มี CPU ที่เหมาะสม

ผมเขียนไม่กี่ตัวอย่างที่นี่และที่นี่


4

ฉันมักจะทำงานกับเครื่องมือบรรทัดคำสั่งของ RDBMS เพียงแค่มี 2 (หรือมากกว่า) อินสแตนซ์ของ CLI เริ่มต้น จากนั้นคุณสามารถเล่นซ้ำทีละรายการและเป็นการแข่งขัน (ซึ่งจะดูเหมือนแอ็คชั่นสวมบทบาท) คำสั่ง SQL ที่เลเยอร์แอปพลิเคชันของคุณกำลังส่ง คุณควรทดลอง / รู้สึกว่าระบบล็อคกำลังทำงานเนื่องจาก CLI ของคุณจะ "หยุด" เล็กน้อยรอให้ปลดล็อคจาก CLI อื่น ๆ

หากฟังดูชัดเจนว่าเป็นโคลนอย่าลังเลที่จะพูดอย่างนั้น ;-)


คุณสามารถยกตัวอย่างทีละขั้นตอนได้หรือไม่ และสามารถเขียนโปรแกรมทดสอบแบบทดสอบเพื่อทำสิ่งเดียวกันได้หรือไม่?
xenoterracide

1

เงื่อนไขการแข่งขันต้องมีการดำเนินการหลายเธรดดังนั้นในการทดสอบยูนิตคุณจะต้องเริ่มต้นหนึ่งหรือหลายเธรด ใน Oracle ฉันจะใช้ DBMS_Scheduler เพื่อเรียกใช้กระบวนการเพื่อจำลองผู้ใช้คนที่สอง หาก PostgreSQL / Perl มีวิธีเริ่มกระบวนการที่สองแบบเป็นระบบคุณควรทำสิ่งนี้ได้:

กระบวนการ 1 กระบวนการ 2

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

เป็นการดีที่ได้เห็นการคิดเกี่ยวกับวิธีจัดการกับสภาพการแข่งขันและที่สำคัญกว่านั้นคือวิธีทดสอบหน่วย


ฉันจะไม่อธิบายการทดสอบเช่นการทดสอบหน่วยเพราะการทดสอบหน่วยต้องทำงานในลักษณะเดียวกันทุกครั้ง สภาพการแข่งขันล้มเหลวเกี่ยวข้องกับกระบวนการเป็นระยะ ๆ ไม่ใช่ในลักษณะเดียวกันทุกครั้ง
AK

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

-2

ตราบใดที่คุณล็อคแถวคุณไม่ควรเข้าร่วมการแข่งขันเพราะมักจะเกิดขึ้นเมื่อไม่มีการล็อค

แต่คุณอาจถูกหยุดชะงักหากคำถามหนึ่งคำถามบล็อกคำถามของคุณนานเกินไป

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

ข้อความค้นหาที่ทำงานได้ดีกับข้อมูลการทดสอบ 100,000 แถวจะดับลงด้วยแผนภูมิที่มี 10,000,000 แถว

ปัญหาประเภทนี้อาจหาได้ยากล่วงหน้า แต่ฐานข้อมูลจำนวนมากมีวิธีการระบุแบบสอบถามที่ช้า

ด้วยการใช้กฎข้อบังคับนั้นคุณจะสามารถดักจับข้อความค้นหาที่มีปัญหาด้วยการเตือนที่เพียงพอ

หากคุณล็อคตัวเองมันเป็นอีกเรื่องหนึ่ง แต่ที่นั่นฉันไม่สามารถช่วยได้


@darioo lol ฉันคิดว่าอาจเป็นคำย่อสำหรับบางสิ่งบางอย่าง ... idk สิ่งที่เขาจะหมายถึงโดย "ทำล็อคด้วยตัวคุณเอง" ถ้าเขาหมายถึงไม่ได้มี ORM ฉันตรวจสอบรหัสของฉันออก ORM มันไม่ได้ทำอย่างแน่นอน ล็อคไปทางขวา ซึ่งเป็นหนึ่งในเหตุผลที่ฉันต้องการทดสอบสถานการณ์ของการแข่งขันที่อาจเกิดขึ้น
xenoterracide

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

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