Eu tenho um gráfico de impasse de um impasse onde um processo está fazendo um SELECT e outro está fazendo um UPDATE. Este parece ser o caso clássico em que o SELECT obtém um bloqueio NCI para executar uma junção e, em seguida, um bloqueio CI para recuperar todos os dados por pesquisa. E o UPDATE está usando o bloqueio do CI para realizar uma atualização e então precisa bloquear um NCI porque a atualização resulta em uma mudança de status e o NCI facilita a localização de itens por status.
O problema é que um dos bloqueios que o UPDATE deseja NÃO está na tabela que está atualizando e não consigo descobrir porque isso está acontecendo.
Aqui está o SELECT:
SELECT *,
RIGHT(c.CC_NUMBER, 4) AS CC_LAST_4,
DATEDIFF(ss, '1970-01-01', plan_started ) plan_started_epoch,
DATEDIFF(ss, '1970-01-01', plan_expires ) plan_expires_epoch
FROM customers c, accounts a, parent_cos pc, htt_customers_overlay_ultra u
WHERE c.customer_id = a.customer_id
AND u.customer_id = c.customer_id
AND a.cos_id=pc.cos_id
AND u.customer_id = 9300;
Aqui está a ATUALIZAÇÃO:
UPDATE htt_customers_overlay_ultra SET plan_state = 'Active' WHERE customer_id = 9300;
Mas de acordo com o gráfico de deadlock, o UPDATE está adquirindo um bloqueio em ACCOUNTS.ACCOUNT0, que é o PK (CI) da tabela ACCOUNTS. Não há chaves estrangeiras na tabela de sobreposição. Existem algumas restrições padrão que atualmente não tenho permissão para ver.
Eu olhei para o gráfico de impasse no SSMS e no SQL Sentry Plan Explorer Pro e não sou o mais sábio.
Seguem os planos de execução:
Eu gostaria de descobrir porque está recebendo esse bloqueio e, em seguida, a melhor maneira de serializar essas chamadas.
Coisas que estou ciente das quais já aconselhei o cliente que têm relação com os bloqueios tomados, mas não explicam o aparente bloqueio não relacionado que está surgindo:
Remova * e identifique as colunas necessárias e altere os NCIs para se tornarem coberturas - isso potencialmente faria o SELECT usar menos bloqueios
Determine por que o sistema está SELECIONANDO os mesmos dados que outro processo está processando - isso potencialmente atenuaria esses dois processos em execução ao mesmo tempo.
Há uma varredura de tabela no SELECT
A
UPDATE
consulta tem umX
bloqueio em uma chave em "dbo.ACCOUNTS" impedindo que elaSELECT
sejaS
bloqueada.A
SELECT
consulta tem umS
bloqueio em uma chave dehtt_customers_overlay_ultra
. AUPDATE
consulta tem umU
bloqueio na mesma chave e é bloqueada tentando convertê-la em umX
bloqueio.O plano de execução para o
UPDATE
não possui nenhum recursoAccounts
, portanto, não há razão óbvia para que ele tenha um bloqueio de chave ativadoAccounts
. A transação Update começa0.01
segundos antes do lote.2013-01-13 08:49:30.213
vs.2013-01-13 08:49:30.223
_Talvez houvesse uma instrução anterior em um lote diferente (portanto, não mostrado no gráfico de deadlock) que realmente iniciou a transação e adquiriu o
X
bloqueio misterioso.