私のデータベースは SQL Server 2005/8 です。予約システムでは、イベントの予約は 24 件に制限されています。ストアド プロシージャ内のこのコードは、次をチェックします。 - 現在のユーザー (@UserId) がイベント (@EventsID) でまだ予約されていないこと - 現在のイベントの現在の予約リストが 24 未満であること - 新しい予約を挿入します。
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
問題は、安全ではないということです。2 人のユーザーが同時にテストを実行し、どちらも予約できると結論付ける場合があります。両方とも行を挿入すると、最終的に 25 の予約になります。
単にトランザクションに含めるだけでは機能しません。一方が更新ロックを取得し、もう一方がロックされないようにすることを期待して、セレクトに WITH (UPDLOCK) を追加してみました。それはうまくいきません。