3 votes

Comment obtenir les bons verrous pour ce SQL ?

Ma base de données est SQL Server 2005/8. Dans un système de réservation, nous avons une limite de 24 réservations pour un événement. Ce code dans une procédure stockée vérifie : - que l'utilisateur actuel (@UserId) n'est pas déjà inscrit à l'événement (@EventsID) - que l'événement en cours a une liste de réservations de moins de 24 personnes - insère une nouvelle réservation.

BEGIN TRANSACTION 
IF (((select count (*) from dbo.aspnet_UsersEvents with (updlock) 
      where UserId = @UserId and EventsId = @EventsId) = 0) 
AND  ((SELECT Count(*)  FROM dbo.aspnet_UsersEvents with (updlock) 
      WHERE EventsId = @EventsId) < 24))
BEGIN
  insert into dbo.aspnet_UsersEvents (UserId, EventsId) 
      Values (@UserId, @EventsId)
END
COMMIT

Le problème est qu'il n'est pas sûr. Deux utilisateurs pourraient effectuer le test simultanément et conclure qu'ils peuvent tous deux réserver. Les deux insèrent une ligne et nous nous retrouvons avec 25 réservations.

Le fait de l'enfermer simplement dans une transaction ne fonctionne pas. J'ai essayé d'ajouter WITH (UPDLOCK) aux sélections dans l'espoir que l'une prenne les verrous de mise à jour et empêche l'autre d'entrer. Cela ne fonctionne pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X