เราเพิ่งโอนย้ายอินสแตนซ์การผลิตของเราจาก SQL 2008 R2 ไปเป็นเซิร์ฟเวอร์ SQL 2014 ใหม่ล่าสุด นี่เป็นสถานการณ์ที่น่าสนใจที่เราค้นพบกับการใช้บริการของเรา พิจารณาฐานข้อมูลที่มีBroker Enabled = true
ด้วยและMyService
MyQueue
การจัดการข้อความพิษถูกปิดใช้งานในคิวนี้ มีการสนทนาอย่างน้อย 2 ครั้งที่มีข้อความในคิว
ในหนึ่งกระบวนการ (SPID 100) ดำเนินการ:
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
โปรดทราบว่าเราปล่อยให้ธุรกรรมเปิดอยู่ ลองนึกภาพว่ามันเป็นโปรแกรม. NET ที่กำลังรอทรัพยากรภายนอกอยู่นาน ผ่านทางsys.dm_tran_locks
เราเห็นว่า SPID นี้ได้รับการล็อคทรงเครื่องบนคิว
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
ในกระบวนการที่แยกต่างหาก (SPID 101) ดำเนินการห้าครั้ง :
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
ROLLBACK TRANSACTION;
ที่สำคัญนี่คือการที่เราจะกลิ้งกลับการทำธุรกรรมครั้งที่ห้า สิ่งนี้ทริกเกอร์ตรรกะพื้นหลังการจัดการข้อความพิษที่สร้างขึ้น ในขณะที่คิวไม่ได้ถูกปิดใช้งาน (เนื่องจากถูกกำหนดค่าเป็นไม่ปิดใช้งาน) งานพื้นหลังยังคงพยายามทำงานและเริ่มต้นbroker_queue_disabled
เหตุการณ์ ดังนั้นตอนนี้ถ้าเราสอบถามsys.dm_tran_locks
อีกครั้งเราจะเห็น SPID อื่น (เกี่ยวข้องกับBRKR TASK
) รอการล็อคแบบ Sch-M
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
| OBJECT | 277576027 | Sch-M | WAIT | 36 |
จนถึงตอนนี้ทุกอย่างเข้าท่า
ในขั้นตอนอื่น (SPID 102) ให้ลองส่งบริการโดยใช้คิวนั้น:
BEGIN TRANSACTION;
DECLARE @ch uniqueidentifier;
BEGIN DIALOG @ch FROM SERVICE [MyService] TO SERVICE 'MyService';
SEND ON CONVERSATION @ch ('HELLO WORLD');
SEND
คำสั่งจะถูกปิดกั้น ถ้าเราดูอีกครั้งsys.dm_tran_locks
เราจะเห็นว่ากระบวนการนี้กำลังรอการล็อค Sch-S การดำเนินการsp_who2
เราพบว่า SPID 102 ถูกปิดกั้นโดย SPID 36
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
| OBJECT | 277576027 | Sch-M | WAIT | 36 |
| OBJECT | 277576027 | Sch-S | WAIT | 102 |
เหตุใดการล็อค Sch-S จึงรอการล็อค Sch-M ที่รออยู่ด้วย
พฤติกรรมนี้แตกต่างอย่างสิ้นเชิงใน SQL 2008 R2! การใช้สถานการณ์เดียวกันนี้โดยทำงานในอินสแตนซ์ 2008R2 ที่ยังไม่เป็นที่เรียบร้อยของเราแบทช์สุดท้ายรวมถึงSEND
คำสั่งจะไม่ถูกบล็อกโดยล็อค Sch-M ที่รออยู่
พฤติกรรมการล็อคเปลี่ยนไปใน SQL 2012 หรือ 2014 หรือไม่ อาจมีการตั้งค่าฐานข้อมูลหรือเซิร์ฟเวอร์บางอย่างซึ่งอาจมีผลต่อพฤติกรรมการล็อคนี้หรือไม่?
SEND
บล็อกขณะที่การตรวจสอบริเริ่มคิว SEND
จะไม่ปิดกั้นคิวเป้าหมายมันจะเด้งและใช้sys.transmission_queue
สำหรับการจัดส่ง หากคุณแยกทั้งสอง (เป็นความคิดที่ดีเสมอ) คุณจะไม่มีปัญหา