Gần đây chúng tôi đã di chuyển các phiên bản sản xuất của chúng tôi từ SQL 2008 R2 sang các máy chủ SQL 2014 hoàn toàn mới. Đây là một kịch bản thú vị mà chúng tôi đã phát hiện ra khi sử dụng Nhà môi giới dịch vụ. Hãy xem xét một cơ sở dữ liệu Broker Enabled = true
với MyService
và MyQueue
. Xử lý tin nhắn độc bị vô hiệu hóa trên hàng đợi này. Có ít nhất 2 cuộc hội thoại hoạt động với các tin nhắn trong hàng đợi.
Trong một quy trình (SPID 100) thực thi:
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
Lưu ý rằng chúng tôi để giao dịch mở. Hãy tưởng tượng rằng đó là một chương trình .NET đang chờ một thời gian dài trên một số tài nguyên bên ngoài. Qua sys.dm_tran_locks
chúng tôi thấy rằng SPID này đã được cấp khóa IX trên hàng đợi.
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
Trong một quy trình riêng biệt (SPID 101) thực hiện năm lần :
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
ROLLBACK TRANSACTION;
Chìa khóa ở đây là chúng tôi đang quay lại giao dịch năm lần . Điều này kích hoạt logic nền xử lý thông điệp Poison tích hợp. Mặc dù hàng đợi không bị vô hiệu hóa (vì nó được cấu hình để không vô hiệu hóa), một tác vụ nền vẫn đang cố gắng thực hiện công việc và thực hiện một broker_queue_disabled
sự kiện. Vì vậy, bây giờ nếu chúng ta truy vấn sys.dm_tran_locks
lại, chúng ta sẽ thấy một SPID khác (được liên kết với BRKR TASK
) đang chờ trên khóa Sch-M.
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
| OBJECT | 277576027 | Sch-M | WAIT | 36 |
Cho đến nay, mọi thứ đều có ý nghĩa.
Cuối cùng, trên một quy trình khác (SPID 102), hãy thử GỬI đến một Dịch vụ bằng cách sử dụng Hàng đợi đó:
BEGIN TRANSACTION;
DECLARE @ch uniqueidentifier;
BEGIN DIALOG @ch FROM SERVICE [MyService] TO SERVICE 'MyService';
SEND ON CONVERSATION @ch ('HELLO WORLD');
Các SEND
lệnh được chặn. Nếu chúng ta nhìn lại sys.dm_tran_locks
chúng ta sẽ thấy rằng quá trình này đang chờ khóa Sch-S. Thực hiện sp_who2
chúng tôi thấy rằng SPID 102 bị chặn bởi 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 |
Tại sao khóa Sch-S lại đợi trên khóa Sch-M cũng đang chờ?
Hành vi này là hoàn toàn khác nhau trong SQL 2008 R2! Sử dụng chính xác kịch bản này, chạy trên các phiên bản 2008R2 sắp ngừng hoạt động của chúng tôi, lô cuối cùng bao gồm SEND
lệnh không bị chặn bởi khóa Sch-M đang chờ.
Hành vi khóa đã thay đổi trong SQL 2012 hoặc 2014? Có lẽ có một số cơ sở dữ liệu hoặc cài đặt máy chủ có thể ảnh hưởng đến hành vi khóa này?
SEND
khối trong khi kiểm tra hàng đợi khởi tạo . SEND
sẽ không chặn trên hàng đợi đích , nó chỉ đơn giản là bị trả lại và sử dụng sys.transmission_queue
để phân phối. Nếu bạn tách hai người (luôn luôn là một ý tưởng tốt), bạn sẽ không gặp vấn đề gì.