As duas consultas que causam o impasse são o
SELECT
abaixo (process id="process3980de4558"
):select @existing = team_it_cube_attr_05 from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key
E a
UPDATE
consulta abaixo (process id="process386ed48188"
):UPDATE D
SET D.team_rss_attr_01 = LEFT(S.mkt_prodchar_13,25)...
O
<resource-list>
seção observa o SELECT
query possuía um bloqueio exclusivo (X) em uma página e estava tentando adquirir um bloqueio de intenção compartilhada (IS) em outra página enquanto estava lendo dados. A UPDATE
query já possuía um bloqueio IS e estava tentando adquirir um bloqueio X em uma página para realizar a atualização. Dada a junção contra esta tabela:
...from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key...
...INNER JOIN tbl_Ref_Attr_Prod_Team D ON D.prod_key=P.prod_key...
O
SELECT
query já possui um bloqueio exclusivo. Isso provavelmente significa que é parte de uma transação maior que já executou um UPDATE
em uma consulta prévia. Os bloqueios de consultas anteriores serão mantidos para preservar a integridade dos dados durante a transação (dependendo do nível de isolamento da transação
). A
UPDATE
a consulta precisa ler a tabela tbl_Ref_Attr_Prod_team
. Ele adquire bloqueios compartilhados por intenção em páginas e linhas durante a leitura de dados. Quando o UPDATE
consulta encontrar as linhas correspondentes, ela tentará converter os bloqueios IS em bloqueios X. Os bloqueios IS não são compatíveis com os bloqueios X. Porque o SELECT
consulta já tem um bloqueio IS em uma ou mais dessas páginas, as consultas travam entre si. Uma causa possível seria a falta de índices em
tbl_Ref_Attr_Prod_team.prod_key
. Sem um índice nesta coluna, o UPDATE
consulta verificará todas as linhas na tabela tbl_Ref_Attr_Prod_team
. Mesmo que exista um índice em
prod_key
, se houver um pequeno número de linhas na tabela, o SQL Server poderá decidir que o desempenho seria melhor se a consulta verificasse a tabela inteira em vez de buscar o índice. Gravar o plano de consulta quando ocorre o deadlock verificaria essa teoria. Encontramos pequenos bloqueios de tabela regularmente ao preparar novos bancos de dados. Inicialmente, as tabelas são pequenas e as varreduras de tabela causam todos os tipos de deadlocks. Mais tarde, quando as tabelas são maiores, o custo calculado de varredura da tabela excede o custo de busca do índice e os deadlocks não ocorrem mais. Em ambientes de teste onde o número de linhas é sempre pequeno, recorremos ao uso de
FORESEEK
e WITH INDEX
dicas para forçar buscas de índice em vez de varreduras. Estamos ansiosos para poder forçar planos de consulta por meio do recurso de armazenamento de consultas do SQL Server 2016.