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.