ใน SQL Server การ Lock คือกลไกที่ Database Engine ใช้เพื่อจัดการการเข้าถึงข้อมูลของผู้ใช้หลายคนพร้อมกัน ( Concurrency Control ) เพื่อไม่ให้ข้อมูลเกิดความขัดแย้งกัน เช่น คนหนึ่งกำลังแก้ อีกคนกำลังอ่าน หรือแก้ไขพร้อมกันจนข้อมูลเพี้ยน
ลำดับขั้นของ Object ( Lock Hierarchy )
SQL Server ไม่ได้ Lock แค่ “ตาราง” เสมอไป แต่มันฉลาดพอที่จะเลือก Lock ในระดับที่เล็กลงเพื่อประหยัดทรัพยากร โดยไล่ลำดับดังนี้
- RID ( Row ID ): Lock เฉพาะแถวเดียวใน Heap
- Key: Lock เฉพาะแถวเดียวใน Index
- Page: Lock ข้อมูลขนาด 8 KB ( ซึ่งอาจมีหลายแถว )
- Extent: Lock กลุ่มของ Page ( 64 KB )
- Table ( Object ): Lock ทั้งตาราง
- Database: Lock ทั้งฐานข้อมูล ( มักเกิดขึ้นตอน Restore หรือเปลี่ยน Config )
โหมดการ Lock ที่ใช้บ่อย ( Lock Modes )
เพื่อให้เข้าใจง่าย ให้มองว่า Lock มี 3 โหมดหลักที่สู้กันอยู่
| โหมดการ Lock | ชื่อเรียก | คำอธิบาย |
| Shared (S) | อ่านอย่างเดียว | ใช้ตอน SELECT ยอมให้คนอื่นอ่านได้พร้อมกัน แต่ห้ามใครแก้ |
| Exclusive (X) | เขียน/แก้ไข | ใช้ตอน INSERT/UPDATE/DELETE ห้ามคนอื่นอ่านและห้ามแก้เด็ดขาด |
| Intent (IS, IX) | การจองล่วงหน้า | ใช้บอกในระดับบน (เช่น Page/Table) ว่าข้างในมี Row ที่โดน Lock อยู่ เพื่อป้องกันไม่ให้ใครมา Lock ทั้งตารางทับซ้อน |
ปรากฏการณ์ “Lock Escalation”
บางครั้งถ้าคุณแก้ข้อมูลจำนวนมหาศาล ( เช่น Update 1 ล้านแถว ) SQL Server จะมองว่าการเก็บ Lock ระดับ Row 1 ล้านตัวนั้นเปลือง Memory มากเกินไป มันจะทำการ “ยกระดับการ Lock” ( Escalation ) จากระดับ Row ขึ้นไปเป็นระดับ Table Lock ทันที เพื่อประหยัดทรัพยากรระบบ
ข้อควรระวัง: เมื่อเกิด Escalation คนอื่นจะเข้าใช้งานตารางนั้นไม่ได้เลยจนกว่างานคุณจะเสร็จ
เทคนิคการเลี่ยงปัญหา Lock
ถ้าคุณจำเป็นต้องอ่านข้อมูลในตารางที่มีการ Update ตลอดเวลา และไม่ซีเรียสเรื่องความแม่นยำ 100% (ยอมรับ Dirty Read ได้) คุณสามารถใช้
WITH (NOLOCK): เช่นSELECT * FROM Orders WITH (NOLOCK)เพื่อให้อ่านผ่านไปได้เลยโดยไม่ต้องรอ LockREAD_COMMITTED_SNAPSHOT: ตั้งค่า Database ให้ใช้ระบบ “สำเนาข้อมูล” เพื่อให้การอ่านและการเขียนไม่ขวางทางกัน ( แนะนำวิธีนี้ที่สุดในระบบสมัยใหม่ )
อ่านเพิ่มเติม
About the author