Question

J'ai une procédure stockée pour SQL Server 2000 qui ne peut exécuter qu'une seule instance à un moment donné. Existe-t-il un moyen de vérifier et d’assurer que la procédure n’est pas en cours d’exécution?

Idéalement, j'aimerais que le code soit autonome et efficace (rapide). Je ne souhaite pas non plus créer une table temporaire globale pour vérifier son existence, car si la procédure échoue pour une raison quelconque, elle sera toujours considérée comme en cours d'exécution ...

J'ai cherché, je ne pense pas que cela ait été demandé pour le moment. Si tel est le cas, désolé.

Était-ce utile?

La solution

oui il y a un moyen. utilisez ce qui est appelé Verrous d'application SQL Server .

EDIT: oui, cela fonctionne également dans SQL Server 2000 .

Autres conseils

Vous pouvez utiliser sp_getapplock sp_releaseapplock comme dans l'exemple trouvé dans Verrouiller un Procédure stockée à usage unique uniquement .

Mais, est-ce ce que vous essayez vraiment de faire? Essayez-vous d'obtenir une transaction avec un niveau d'isolement élevé ? Vous auriez probablement aussi intérêt à gérer ce type de concurrence au niveau de l'application, car les langages de niveau supérieur ont généralement de meilleures primitives pour ce type de choses.

que diriez-vous de verrouiller une table factice? Cela ne provoquerait aucune impasse en cas d'échec.

Au début de la procédure, vérifiez si une donnée est verrouillée sinon verrouillée

En fin de procédure, déverrouillez la donnée.

c'est-à-dire

SELECT @IsLocked=IsLocked FROM CheckLockedTable Where spName = 'this_storedProcedure'

IF @IsLocked = 1
    RETURN
ELSE
    UPDATE CheckLockedTable SET IsLocked = 1 Where spName = 'this_storedProcedure'

.
.
.

-- At end of Stored Procedure
    UPDATE CheckLockedTable SET IsLocked = 0 Where spName = 'this_storedProcedure'

L'un des liens externes initiaux partagés dans les réponses contenait des informations utiles, mais personnellement, je préfère que les réponses / extraits autonomes soient ici, ici, sur la page de question relative au dépassement de capacité. Voir l'extrait ci-dessous pour ce que j'ai utilisé et résolu mon problème (similaire). Si vous avez des problèmes (ou des suggestions d’ajustement), envoyez-nous un message

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[MyLockedAndDelayedStoredProcedure]') AND type in (N'P', N'PC'))
DROP PROCEDURE [GetSessionParticipantAnswersFromEmailAddressAndSessionName]
GO

CREATE PROCEDURE [MyLockedAndDelayedStoredProcedure]    
  @param1 nvarchar(max) = ''
AS
BEGIN

DECLARE @LockedTransactionReturnCode INT
PRINT 'MyLockedAndDelayedStoredProcedure CALLED at ' + CONVERT(VARCHAR(12),GETDATE(),114);
BEGIN TRANSACTION
EXEC @LockedTransactionReturnCode =sp_getapplock @Resource='MyLockedAndDelayedStoredProcedure_LOCK', @LockMode='Exclusive', @LockOwner='Transaction', @LockTimeout = 10000
PRINT 'MyLockedAndDelayedStoredProcedure STARTED at ' + CONVERT(VARCHAR(12),GETDATE(),114);

-- Do your Stored Procedure Stuff here
Select @param1;

-- If you don't want/need a delay remove this line    
WAITFOR DELAY '00:00:3'; -- 3 second delay
PRINT 'MyLockedAndDelayedStoredProcedure ENDED at ' + CONVERT(VARCHAR(12),GETDATE(),114);
COMMIT

END

-- https://gist.github.com/cemerson/366358cafc60bc1676f8345fe3626a3f
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top