SQL Server - ระดับการแยกใดสำหรับคำสั่ง select ที่ไม่ได้บล็อก?


9

ฉันมีธุรกรรมที่ใช้เวลานาน (เรียกว่า, T1) ที่ดำเนินการลบปรับปรุงและแทรกบางอย่างในตารางใน SQL Server 2008 R2 ในเวลาเดียวกันกระบวนการอื่นเรียกใช้คำสั่งที่เลือกจากตารางนี้เป็นระยะ

ภายใต้การตั้งค่าการแยกเริ่มต้น (READ COMMITTED ฉันคิดว่า?) T1 จะบล็อกคำสั่งที่เลือกไม่ให้ทำงานจนกว่าธุรกรรมจะทำหน้าที่หรือย้อนกลับ

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

ประการที่สองฉันไม่มีการควบคุมกระบวนการที่เรียกใช้คำสั่ง select แต่ฉันมีการควบคุมแอปพลิเคชัน. NET ที่เรียก T1 การเปลี่ยนแปลงระดับการแยกใด ๆ จะต้องการทั้งข้อความสั่งการเลือกและ T1 หรือว่าจะเพียงพอที่จะทำเครื่องหมายว่า T1 มีระดับการแยกต่างกันหรือไม่

คำตอบ:


8

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

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


6

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

การแยกแบบ READ UNCOMMITTED (aka NOLOCK hint) จะอ่านข้อมูลที่สกปรกและไม่สอดคล้องกัน

เมื่อคุณเปิดใช้งานการแยก SNAPSHOT จะมีผลสำหรับการเลือกทั้งหมดในอนาคต คุณรันALTER DATABASEด้วย READ_COMMITTED_SNAPSHOT ในกรณีนี้

แก้ไข: เพิ่มลิงค์ + คำพูดของ ALTER DATABASE (ตัวหนาของฉัน)

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

และจากการใช้ Snapshot Isolation (ตัวหนาของฉัน)

ตัวเลือกฐานข้อมูล READ_COMMITTED_SNAPSHOT กำหนดลักษณะการทำงานของระดับการแยก READ COMMITTEDเริ่มต้นเมื่อเปิดใช้งานการแยกสแน็ปช็อตในฐานข้อมูล หากคุณไม่ได้ระบุ READ_COMMITTED_SNAPSHOT ไว้อย่างชัดเจน READ COMMITTED จะถูกนำไปใช้กับธุรกรรมโดยนัยทั้งหมด สิ่งนี้สร้างพฤติกรรมเช่นเดียวกับการตั้งค่า READ_COMMITTED_SNAPSHOT OFF (ค่าเริ่มต้น) เมื่อ READ_COMMITTED_SNAPSHOT OFF มีผลบังคับใช้กลไกจัดการฐานข้อมูลจะใช้การล็อกที่ใช้ร่วมกันเพื่อบังคับใช้ระดับการแยกเริ่มต้น หากคุณตั้งค่าตัวเลือกฐานข้อมูล READ_COMMITTED_SNAPSHOT เป็น ON เอ็นจิ้นฐานข้อมูลจะใช้การแยกเวอร์ชันและการแยกสแนปชอตเป็นค่าเริ่มต้นแทนที่จะใช้การล็อกเพื่อป้องกันข้อมูล

ใช่.

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


4

ฉันขอแนะนำให้คุณอ่านคำถามและคำตอบต่อไปนี้: ปัญหาการล็อกฐานข้อมูล .

การค้นหาระดับการแยกที่ถูกต้องเพื่อใช้ที่ระดับ db เป็นสิ่งที่เร็วที่สุดที่คุณสามารถทำได้ในตอนนี้เพื่อช่วยคุณแก้ไขปัญหานี้เพราะตอนนี้การเปลี่ยนแอปพลิเคชันทั้งหมดที่สัมผัสกับฐานข้อมูลและเปลี่ยนรหัสเป็นเรื่องยาก เนื่องจากคุณพูดว่า "ฉันไม่สามารถควบคุมกระบวนการที่เรียกใช้คำสั่ง select" คำตอบที่เร็วที่สุดคือการเปลี่ยน db เป็นระดับการแยก Snapshot ของ Read Committed Snapshot ดังนั้นคุณจะไม่สัมผัสคำสั่งการอ่าน มิฉะนั้นคุณจะต้องใช้ระดับการแยก Snapshot สำหรับเซสชันที่อ่านข้อมูลในระหว่างการทำธุรกรรมครั้งใหญ่ของคุณ

รายละเอียดเพิ่มเติมที่นี่เกี่ยวกับการเลือกหนึ่งที่เหมาะสม: การเลือกแถวรุ่นตามระดับการแยก

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