Kısa bir süre önce üretim örneklerimizi SQL 2008 R2'den yeni SQL 2014 sunucularına taşıdık. Hizmet Aracısı kullanımımızla ortaya çıkardığımız ilginç bir senaryo. İçeren bir veri tabanı düşünün Broker Enabled = true
ile MyService
ve MyQueue
. Bu kuyrukta zehirli mesaj işleme devre dışı bırakıldı. Kuyrukta mesajlar içeren en az 2 aktif görüşme vardır.
Bir işlemde (SPID 100) şunları yürütün:
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
İşlemi açık bıraktığımızı unutmayın. Bazı harici kaynaklarda uzun süre bekleyen bir .NET programı olduğunu düşünün. Via sys.dm_tran_locks
bu SPID kuyruğunda bir IX kilidi verilmiş olduğunu görüyoruz.
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
Ayrı bir işlemde (SPID 101) beş kez yürütün :
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
ROLLBACK TRANSACTION;
Buradaki anahtar, işlemi beş kez geri almamızdır . Bu yerleşik Zehir Mesaj İşleme arka plan mantığını tetikler . Kuyruk devre dışı bırakılmasa da (devre dışı bırakılmayacak şekilde yapılandırıldığı için), arka plan görevi hala bir iş yapmaya ve bir broker_queue_disabled
olayı başlatmaya çalışıyor . Şimdi sys.dm_tran_locks
tekrar sorgularsak BRKR TASK
, bir Sch-M kilidinde bekleyen farklı bir SPID (ile ilişkili ) göreceğiz .
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
| OBJECT | 277576027 | Sch-M | WAIT | 36 |
Şimdiye kadar her şey mantıklı.
Son olarak, farklı bir işlemde (SPID 102), bu Kuyruğu kullanarak bir Hizmete GÖNDERMEYİ deneyin:
BEGIN TRANSACTION;
DECLARE @ch uniqueidentifier;
BEGIN DIALOG @ch FROM SERVICE [MyService] TO SERVICE 'MyService';
SEND ON CONVERSATION @ch ('HELLO WORLD');
SEND
Komut engellendi. Tekrar sys.dm_tran_locks
bakarsak, bu sürecin bir Sch-S kilidinde beklediğini görürüz. Yürütülmesi sp_who2
biz SPID 102 SPID 36 tarafından engellenir bulmak.
| 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 kilidi neden bekleyen Sch-M kilidini bekliyor?
Bu davranış, SQL 2008 R2'de tamamen farklıdır! Bizim üzerinde çalışan, bu aynı senaryoyu kullanarak 2008R2 örneklerini içeren nihai yığın henüz-to-hizmet dışı bırakılmış SEND
komuta etmez bekleyen Sch-M kilit tarafından engellenir.
SQL 2012 veya 2014'te kilitleme davranışı değişti mi? Bu kilitleme davranışını etkileyebilecek bazı veritabanı veya sunucu ayarları var mı?
SEND
Bloklar kontrol ederken başlatıcı kuyruğu. hedef kuyruğu SEND
engellemezse, hemen sıçrar ve dağıtım için kullanır . Eğer ikisini ayırırsanız (her zaman iyi bir fikir) sorun olmazdı. sys.transmission_queue