我的数据库是SQL Server 2005/8。在预订系统中,我们有24项预定的活动限制。存储过程中的此代码将检查: - 当前用户(@UserId)尚未在事件(@EventsID) 上预订 - 当前事件的当前预订列表为24 - 插入新的预订。如何获得此SQL的正确锁定?
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
问题是它不安全。两个用户可能会同时进行测试并得出结论,他们都可以预订。插入一行,我们结束了25个预订。
简单地将它包含在事务中不起作用。我尝试添加WITH(UPDLOCK)到选择中,希望能够更新锁并保持其他锁。这是行不通的。
为什么这么复杂?看到我的答案。 –
因为你的答案不是事务安全的。单一的陈述总是一致的是一个常见的谬误。 –
请您指出一些SQL Server不能保证单个语句不一致的文档。我假设他没有以'READ UNCOMMITTED'运行。 –