Você precisa investigar isso no lado do servidor para entender por que a execução está expirando. Observe que o servidor não tem tempo limite, o tempo limite é causado pelo padrão de 30 segundos em
SqlCommand.CommandTimeout
. Um bom recurso é Waits and Queues , que é uma metodologia para diagnosticar gargalos de desempenho com o SQL Server. Com base na causa real do tempo limite, a ação adequada pode ser tomada. Você deve estabelecer em primeiro lugar se está lidando com execução lenta (um plano ruim) ou bloqueio.
Se eu arriscasse um palpite, diria que o padrão não saudável de
IF EXISTS... UPDATE
é a causa raiz. Esse padrão está incorreto e causará falhas em simultaneidade. Duas transações simultâneas executando o IF EXISTS
simultaneamente chegarão à mesma conclusão e ambos tente INSERT
ou UPDATE
. Dependendo das restrições existentes no banco de dados, você pode acabar com um impasse (o caso de sorte) ou com uma gravação perdida (o caso de azar). No entanto, apenas uma investigação adequada revelaria a causa raiz real. Pode ser algo totalmente diferente, como eventos de crescimento automático
. Seu procedimento também está manipulando incorretamente o bloco CATCH. Você deve sempre verifique o
XACT_STATE()
porque a transação já pode ser revertida no momento em que seu bloco CATCH for executado. Também não está claro o que você espera de nomear a transação, esse é um erro comum que vejo frequentemente associado a transações nomeadas confusas com pontos de salvamento. Para obter um padrão correto, consulte Tratamento de exceção e transações aninhadas . Editar
Aqui está uma maneira possível de investigar isso:
- Altere o
CommandTimeout
para 0 (ou seja, infinito). - Ative o
blocked process threshold
, defina-o para 30 segundos (o antigo CommandTimeout) - Monitore no Profiler para Evento de relatório de processo bloqueado
- Inicie sua carga de trabalho
- Veja se o Profiler produz algum evento de relatório. Se isso acontecer, eles identificarão a causa.
Essas ações causarão um evento de 'relatório de processo bloqueado' toda vez que você tiver um tempo limite, se o tempo limite for causado por bloqueio. Seu aplicativo continuará aguardando até que o bloqueio seja removido, se o bloqueio for causado por um bloqueio ao vivo então vai esperar para sempre.