Recentemente, migramos nossas instâncias de produção do SQL 2008 R2 para novos servidores SQL 2014. Aqui está um cenário interessante que descobrimos com o uso do Service Broker. Considere um banco de dados Broker Enabled = truecom MyServicee MyQueue. O tratamento de mensagens suspeitas está desabilitado nesta fila. Existem pelo menos 2 conversas ativas com mensagens na fila.
Em um processo (SPID 100), execute:
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
Observe que deixamos a transação aberta. Imagine que é um programa .NET que está aguardando muito tempo em algum recurso externo. Via sys.dm_tran_locksvemos que esse SPID recebeu um bloqueio IX na fila.
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
Em um processo separado (SPID 101), execute cinco vezes :
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
ROLLBACK TRANSACTION;
A chave aqui é que estamos revertendo a transação cinco vezes . Isso aciona a lógica de fundo de manipulação de mensagens de veneno incorporada . Embora a fila não seja desabilitada (porque está configurada para não desabilitar), uma tarefa em segundo plano ainda está tentando executar o trabalho e disparar um broker_queue_disabledevento. Então, agora, se consultarmos sys.dm_tran_locksnovamente, veremos um SPID diferente (associado a BRKR TASK) aguardando um bloqueio Sch-M.
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
| OBJECT | 277576027 | Sch-M | WAIT | 36 |
Até agora, tudo faz sentido.
Finalmente, em um processo diferente (SPID 102), tente ENVIAR para um serviço usando essa fila:
BEGIN TRANSACTION;
DECLARE @ch uniqueidentifier;
BEGIN DIALOG @ch FROM SERVICE [MyService] TO SERVICE 'MyService';
SEND ON CONVERSATION @ch ('HELLO WORLD');
O SENDcomando está bloqueado. Se olharmos novamente sys.dm_tran_locks, vemos que esse processo está aguardando um bloqueio Sch-S. Ao executar sp_who2, descobrimos que o SPID 102 está bloqueado pelo 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 |
Por que um bloqueio Sch-S aguarda um bloqueio Sch-M que também está aguardando?
Esse comportamento é completamente diferente no SQL 2008 R2! Usando exatamente esse mesmo cenário, executando em nossas instâncias 2008R2 ainda a serem descomissionadas, o lote final, incluindo o SENDcomando , não é bloqueado pelo bloqueio Sch-M em espera.
O comportamento do bloqueio foi alterado no SQL 2012 ou 2014? Existe talvez alguma configuração de banco de dados ou servidor que possa afetar esse comportamento de bloqueio?
SENDblocos enquanto verifica a fila do iniciador . SENDnão bloquearia na fila de destino , simplesmente retornaria e seria usada sys.transmission_queuepara entrega. Se você separar os dois (sempre uma boa ideia), não terá o problema.