ล็อคสร้างตาราง


19

ในแอปพลิเคชันอื่นฉันรู้สึกประทับใจกับการออกแบบที่ไม่ดี: มีหลายเธรดที่รันEnsureDatabaseSchemaExists()เมธอดพร้อมกันซึ่งมีลักษณะดังนี้:

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'MyTable') AND type = N'U') BEGIN

    CREATE TABLE MyTable ( ... );

END

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

มีรูปแบบที่ดีกว่าสำหรับวิธีการแบบมัลติเธรด -CheckSchemaExists () หรือไม่?

คำตอบ:


18

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

สภาพการแย่งชิงในรหัสต้นฉบับคือเธรดจำนวนมากสามารถสรุปว่าตารางไม่มีอยู่ก่อนที่เธรดใด ๆ จะได้รับเท่าที่มีCREATE TABLEคำสั่ง


6
1 เพียงให้แน่ใจว่า applock wraps เช็ค มิฉะนั้นคุณจะแนะนำการหยุดชะงัก ถ้าอย่างนั้นจะมีการล็อคแอพในโหมด S, ตรวจสอบ, อัปเกรดเป็น X แต่นั่นเป็นเรื่องยาก (พูดน้อย ... ) ตัวเลือกที่ปลอดภัยที่สุดคือการรับ X จากนั้นทำการปรับใช้ DB schema ทั้งหมด มันควรจะเป็น op ที่หายาก (เช่นเมื่อเริ่มต้นแอป) ดังนั้นการล็อก X ไม่ควรสำคัญมาก
Remus Rusanu

12

คำแนะนำของฉันคือพยายาม / พยายามอย่างดีที่สุด จัดการกรณีที่ซ้ำกันอย่างชัดเจนตามความเหมาะสมเช่น ไม่สนใจมัน ...

คำถามจริง: เหตุใด DDL จึงทำงานตามความต้องการจากหลาย ๆ xacts โดยทั่วไปการอัปเกรดและการย้ายข้อมูลเป็นเรื่องที่ร้ายแรงจัดการในช่วงเวลาที่กำหนด ... คุณไม่ต้องการให้การโยกย้าย (รหัสแรก?) เริ่มต้นโดยไม่คาดคิดขั้นตอนการอัปเดตบางอย่างอาจใช้เวลาหลายชั่วโมงบนโต๊ะขนาดใหญ่ การดำเนินการ -data ... )


3
รหัสคือ DatabaseLogger บางชนิดซึ่งสร้างตารางตามต้องการ ไม่มีการโยกย้ายไม่มีธุรกิจที่ตลก อย่างไรก็ตามคุณพูดถูก ฉันจะ refactor รหัสอย่างเหมาะสม
DR

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