Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como se livrar do deadlock em um aplicativo SQL Server 2005 e C#?


Não consigo ver nenhum escopo de transação explícito em seu código, portanto, não sei quais bloqueios já estão em vigor quando você está fazendo sua atualização; também não está claro qual nível de isolamento você está usando. Mas o cenário mais comum nesse tipo de situação é que anteriormente na mesma transação você emitiu um select (bloqueio de leitura) nas mesmas linhas que você está tentando atualizar posteriormente. Isso causará uma escalada de bloqueio e poderá resultar em um impasse se duas transações estiverem tentando fazer a mesma coisa:
  1. Transação A:selecione com bloqueio de leitura
  2. Transação B:selecione com readlock
  3. Transação A:atualização - deseja escalar seu bloqueio de leitura para um bloqueio de gravação, mas precisa aguardar a transação B liberar seu bloqueio de leitura
  4. Transação B:atualização - deseja escalar seu bloqueio de leitura para um bloqueio de gravação, mas precisa aguardar que a transação A libere seu bloqueio de leitura.

Bingo! deadlock, pois A e B estão esperando um pelo outro para liberar seus bloqueios de leitura existentes antes que possam fazer sua atualização.

Para evitar isso, você precisa de uma dica de updlock em sua seleção, por exemplo,
select * from table with (updlock) where blah blah

Isso garantirá que sua seleção use um bloqueio de gravação em vez de um bloqueio de leitura, o que impedirá o escalonamento de bloqueio entre transações simultâneas.