Blocage intermittent sur Microsoft SQL Server 2008 avec TABLOCK, commands XLOCK

Je reçois des blocages intermittents avec la procédure stockée suivante. Il est exécuté une fois par minute. Il est en production depuis 1+ ans et nous n'obtenons généralement pas cette erreur mais il arrive parfois … il lance des exceptions 3 à 5 fois par jour dans l'un de nos environnements … c'est le même environnement que d'autres instances ne jetez pas l'erreur. La procédure stockée a été faite afin qu'elle ne puisse fonctionner qu'une fois à la fois, mais peut-être que la façon dont nous le faisons n'est pas correcte?

Voici l'erreur:

System.Web.HttpUnhandledException: Exception du type 'System.Web.HttpUnhandledException' a été levée. —> System.Data.SqlClient.SqlException: La transaction (ID de process 60) a été bloquée sur les ressources de locking avec un autre process et a été choisie comme victime de blocage. Réexécutez la transaction.

Voici la procédure stockée:

SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[requestUpdate] AS SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRAN DECLARE @StartDate datetime, @EndDate datetime, @Throttle bit, @Expired bit SELECT @Throttle = 0 SELECT @Expired = 0 SELECT TOP 1 @StartDate = uq.StartDate, @EndDate = uq.EndDate FROM UpdateQueue uq WITH(TABLOCK,XLOCK) ORDER BY ID DESC -- PREVENT ANOTHER REQUEST IF THIS SP HAS BEEN -- CALLED IN THE LAST FORTY SECONDS. IF DATEADD(SECOND,-40,GETDATE()) < @StartDate BEGIN SELECT @Throttle = 1 END -- CREATE ANOTHER REQUEST IF THE CURRENT ONE -- HAS NOT COMPLETED IN THE LAST FIVE MINUTES. IF @StartDate <= DATEADD(MINUTE,-5,GETDATE()) BEGIN SELECT @Expired = 1 END -- HAS THE CURRENT REQUEST EXPIRED? IF @EndDate IS NULL AND @Expired = 1 BEGIN INSERT INTO UpdateQueue (RequestID, StartDate) OUTPUT 'EXPIRED' AS Result, INSERTED.RequestID AS RequestID VALUES (NEWID(), GETDATE()) END -- HAS THE CURRENT REQUEST COMPLETED AND YOU ARE NOT THROTTLING -- OR HAVE THERE NOT BEEN ANY REQUESTS YET? ELSE IF (@EndDate IS NOT NULL AND @Throttle = 0) OR @StartDate IS NULL BEGIN INSERT INTO UpdateQueue (RequestID, StartDate) OUTPUT 'STARTED' AS Result, INSERTED.RequestID AS RequestID VALUES (NEWID(), GETDATE()) END -- Running ELSE BEGIN SELECT 'RUNNING' AS Result, NULL AS RequestID END COMMIT 

Je soupçonne qu'il s'agit d'un verrou particulier détenu pendant plus longtime que votre connection est prête à attendre. Sans quelque chose pour tuer une transaction de longue durée, ici, vous allez vous heurter à cela car lorsque la connection expire, SQL Server force l'attente à se terminer et détruit le verrou entrant en tant que victime de blocage.

Longue histoire courte: un certain process (pas celui détaillé ici) verrouille la table, provoquant une impasse.

Examiner ce qui se passe d'autre lorsque vous rencontrez l'impasse – existe-t-il une sauvegarde en cours, ou quelque chose d'autre qui verrouille cette table?