Como os deadlocks são detectados e relatados em um RDBMS?

8

Recebi essa pergunta do tipo de ensaio durante uma entrevista, mas não consegui o emprego. A questão completa foi a seguinte:

Como os deadlocks são detectados e relatados em um RDBMS? Qual é o proprietário da transação e o desenvolvedor do aplicativo responsável por garantir nos cenários de detecção e prevenção?

Shadowcaz
fonte

Respostas:

13

No SQL Server, há um thread separado que periodicamente (padrão 5 segundos, intervalo mais baixo se um conflito acabou de ser detectado) verifica uma lista de esperas por quaisquer ciclos. Ou seja, ele identifica o recurso que um encadeamento está aguardando, depois encontra o proprietário desse recurso e localiza recursivamente qual recurso esse encadeamento está esperando, identificando os encadeamentos que aguardam os recursos uns dos outros.

Se um impasse for encontrado, a vítima será escolhida para ser morta usando este algoritmo:

  1. Identifique threads que não são passíveis de inabilidade (por exemplo, uma thread que está revertendo uma transação é inaceitável).
  2. Encontre o encadeamento com a menor prioridade de conflito.
  3. Escolha o que é mais barato para reverter, ou seja, aquele que fez menos trabalho até agora.

Você pode encontrar mais informações sobre a detecção de conflito de servidores SQL aqui: http://msdn.microsoft.com/en-us/library/ms178104.aspx



O proprietário da transação / desenvolvedor do aplicativo é responsável por minimizar os riscos de ocorrência de conflitos e que eles deveriam:

  1. Certifique-se de manter as transações o mais curtas possível. Por exemplo, não mostre um formulário de login após iniciar uma transação e aguarde a entrada do usuário; em vez disso, reúna todas as informações necessárias e execute a transação.
  2. Use o nível de isolamento mais baixo possível, por exemplo, não defina serializável quando quiser mostrar temporariamente alguns valores para o usuário. Observe que definir o nível correto de isolamento é uma ciência em si e fora do escopo nesta resposta.
  3. Se você é vítima de um impasse, ou seja, recebe o erro nº 1205, execute novamente a transação de forma transparente para o usuário. Como a outra transação concorrente agora adquiriu os recursos esperados e concluídos, é improvável que você encontre o mesmo impasse novamente.
Andreas Ågren
fonte
4. Adquira recursos e execute padrões de atualização / exclusão / inserção na mesma ordem de forma consistente em todo o aplicativo.
ErikE
3
@ErikE freqüentemente não é possível / possível "executar padrões de atualização / exclusão / inserção na mesma ordem de forma consistente em todo o aplicativo", embora esse conselho questionável seja muito popular na Web. Detalhes aqui: sqlblog.com/blogs/alexander_kuznetsov/archive/2010/01/15/…
AK
11
Bons pontos. Mas ainda acho que o esforço vale a pena, desde que não haja ilusão de que sempre será possível ou sempre corrija o problema. A coisa pai / filho é interessante. Que tal excluir em cascata ou adquirir primeiro um bloqueio de atualização nas linhas pai? E se você mesclar sem MERGE, por que não ser consistente? Eu excluo-> atualize-> insira pessoalmente.
ErikE
11
@AlexKuznetsov: Não é uma bala de solucionador, mas não deve ser descartada. Tenho reduzida (não eliminado) impasses dessa maneira, porém: através da análise estática de código executar frequentemente que tinha impasse todos os dias ou 7. Eu sugiro "otimização prematura" aplica etc
GBN
Não concordo com a recomendação número 3. Quando tentamos novamente após conflitos, é muito provável que sobrescrevamos as alterações de outros processos. Precisamos estar cientes de que muito provavelmente alguém modificou os dados que pretendíamos modificar. Especialmente se todos os leitores forem executados sob isolamento de captura instantânea, eles não poderão se envolver em conflitos, o que significa que todas as partes envolvidas em um conflito são gravadoras, modificadas ou tentadas modificar os mesmos dados. Se apenas capturarmos a exceção e tentarmos novamente automaticamente, podemos substituir as alterações de outra pessoa. Isso é chamado de atualizações perdidas, e isso geralmente está errado.
AK