Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Utilisation de SQL Server comme mécanisme de verrouillage des ressources

Vous décrivez essentiellement un flux de travail classique basé sur une file d'attente et vous devriez envisager d'utiliser un vrai file d'attente .

Pour les besoins de la discussion, voici comment vous réalisez ce que vous souhaitez :

  • réclamer une ressource spécifique :SELECT ... FROM resources WITH (UPDLOCK, ROWLOCK) WHERE key = @key . Sera bloqué si la ressource est déjà réclamée. Utilisez les délais d'attente de verrouillage pour renvoyer une exception si la ressource a déjà été réclamée. key doit être indexé et unique.
  • prochaine ressource disponible :SELECT ... FROM resources WITH (UPDLOCK, ROWLOCK, READPAST) ORDER BY <accessorder> . Vous devez définir un ordre par pour exprimer la préférence des ressources (la plus ancienne, la plus prioritaire, etc.)
  • libérer une ressource réclamée :COMMIT votre transaction.

L'essentiel du problème consiste à utiliser les bonnes indications de verrouillage, et ce type de problème nécessite des indications de verrouillage explicites pour être résolu. UPDLOCK agira comme un verrou de « réclamation ». ROWLOCK crée la bonne granularité empêchant le serveur de "s'optimiser" pour verrouiller une page. READPAST vous permet d'ignorer les ressources réclamées. Placer UPDLOCK sur les lignes verrouille la ligne et vous permet de la mettre à jour ultérieurement, mais empêchera d'autres opérations telles que les SELECT ordinaires en lecture validée qui bloqueront sur la ligne verrouillée. L'idée est cependant que vous allez de toute façon mettre à jour la ligne, ce qui placera un verrou X inévitable. Si vous souhaitez que le tableau reste plus disponible, vous pouvez utiliser les verrous d'application au lieu de cela, mais est beaucoup plus difficile à retirer correctement. Vous devrez demander un verrou d'application sur un descripteur de chaîne de la ressource, comme la valeur de la clé, ou un CHECKSUM de la clé ou c'est %%LOCKRES%% évaluer. Les verrous d'application vous permettent de séparer la portée de la "réclamation" d'une transaction en demandant le verrou de l'application au niveau de la "session", mais vous devez ensuite libérer la réclamation manuellement (les verrous d'application à portée de "transaction" sont libérés au moment de la validation) . Attention, il existe mille et une façons de se tirer une balle dans le pied avec les verrous d'application.