【问题标题】:Is (insert into ... select) statement safe about race conditions - SQL Server?(insert into ... select) 语句对于竞争条件是否安全 - SQL Server?
【发布时间】:2015-11-28 05:53:35
【问题描述】:

我有一个在线酒店预订系统,允许多个用户几乎同时进行预订。

当用户请求空闲房间时,系统会执行查询以获取空闲房间,然后以某种方式显示...

现在当用户点击“预订”按钮时,免费房间被发送到服务器进行预订,我正在使用与此非常相似的查询(这是简化的):

Insert into Bookings(room_id) select available_room_id from
dbo.GetAvailableRooms(@StartDate,@EndDate) where available_room_id = @ToBeBookedRoomID;

其中“GetAvailableRooms”是一个 UDF。

我希望通过此查询来测试最新时间是否有可用空间,但我担心这是否会受到竞争条件的影响?我正在考虑某些用户在插入和选择操作之间的时间内预订了该房间的情况......“插入..选择”会保证没有竞争条件吗?

更新: 这是函数sql查询:

select AllDays.day_date,alloted_room_id as available_room_id,pl.room_number from HotelsContractsAllotments hl
inner join PlansRooms pl on pl.room_id = hl.alloted_room_id
inner join HotelsContracts hc on hc.contract_id = hl.allotment_contract_id
inner join Hotels h on h.hotel_id = hc.contract_hotel_id
inner join AllDays on day_date >= hc.contract_starting_date and day_date <= hc.contract_end_date
left join BookingsRooms br on day_date >= br.booking_starting_date and  day_date <= br.booking_end_date and br.booking_room_id = alloted_room_id
where br.booking_room_id is null and day_date >= @StartingDate and day_date <= @EndDate

谢谢。

【问题讨论】:

  • 没有看到来自dbo.GetAvailableRooms 的代码,我希望这会暴露在竞争条件下..
  • 对不起,我刚刚更新了,你能看看吗? @GordonLinoff
  • 我建议使用事务。另请参阅:stackoverflow.com/questions/1071286/…

标签: sql-server race-condition


【解决方案1】:

查看表上的锁定以及使用的提示。根据提供的信息,我希望这对竞争条件开放(即表上没有维护锁)。您可以查看使用 SQL 命中或事务设置锁。那里有一些讨论锁定的帖子。一个看起来与您的问题相关的示例是: SQL Server Table Lock during bulk insert

如果没有连续锁定受SELECT 到INSERT 影响的表,是的,您将面临竞争条件。

注意 - 长时间锁定表会在不同程度上影响性能,具体取决于流量和锁定时间(如果很多用户尝试同时预订,1 秒的差异可能会变得很大)。因此,如果您确实锁定了表,我建议您花一些时间调整您的查询以提高性能。我不会对此多说,因为我没有关于您的数据的任何指标,也不知道您的索引。最好从简单地重新构建查询以首先访问最严格的表开始。我假设这将是包含 alloted_room_id 的表(传递 ID,以便它可以在 WHERE 子句中使用)。

【讨论】:

  • 看看用于在线购物车之类的模型以及它们如何处理如果用户什么都不做就会过期的“保留”资源分配可能是值得的。
猜你喜欢
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
  • 2012-10-18
  • 2011-12-04
  • 2021-01-19
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多