SQL atomic从列表中选择未使用的项并分配给另一个表

时间:2009-12-21 07:34:04

标签: sql-server stored-procedures transactions

我有一个频道列表。如果有的话,我需要使用其中一个并将其分配给会话。如果没有可用的东西,我需要创建一个新的并将其分配给会话,并让调用例程知道它是一个新的频道。

我有以下实现,这似乎有效,但我想知道是否有更好的方法来实现它。

PS。这是在SQL 2000中,否则我会尝试使用更新语句的输出子句。

create procedure [dbo].[ReserveChannelSession]
(
     @ID                     int            output
    ,@ApplicationID          int
    ,@ChannelID              int            output
    ,@IsNewChannel           bit            output
)
as
begin
    begin transaction
        set nocount on
        set @ChannelID = ( select top 1 [ID] from [dbo].[Channels] with (updlock,holdlock) where [InUse] = 0 )
        if @ChannelID is null
        begin
            exec InsertChannel  @ID = @ChannelID output , @InUse = 1  -- create as reserved in use
            set @IsNewChannel = 1;
        end else begin
            update [dbo].[Channels] set [InUse] = 1 where [ID] = @ChannelID
            set @IsNewChannel = 0;
        end
        set nocount off

        if @ChannelID is not null
        begin
            insert into [dbo].[ChannelSessions] (
                 [ApplicationID]
                ,[ChannelID]
            ) values (
                 @ApplicationID
                ,@ChannelID
            )
            set @ID=SCOPE_IDENTITY()
        end
    commit transaction
end

1 个答案:

答案 0 :(得分:1)

我至少会使用updlock,holdlock,rowlock

另请参阅此问题:SQL Server Process Queue Race Condition