Sql 删除并选择不同存储过程中的并发

Sql 删除并选择不同存储过程中的并发,sql,concurrency,Sql,Concurrency,这可能是一个愚蠢的问题,但我不确定我创建这些存储过程的方式是否会导致任何问题 我的select存储过程如下所示: ALTER PROCEDURE [dbo].[GetSRPsToProcess] @CurrentTime DateTime AS BEGIN BEGIN TRAN Tran1 Select TOP 20 * From SRPQueue WITH (updlock, ROWLOCK, readpast) WHERE SR

这可能是一个愚蠢的问题,但我不确定我创建这些存储过程的方式是否会导致任何问题

我的select存储过程如下所示:

ALTER PROCEDURE [dbo].[GetSRPsToProcess]
    @CurrentTime DateTime
AS
BEGIN
    BEGIN TRAN Tran1
        Select TOP 20 *
        From SRPQueue WITH (updlock, ROWLOCK, readpast)
        WHERE SRPQueue.TimeToDequeue <= @CurrentTime AND SRPQueue.Status = 'Pending'
        ORDER BY SRPQueue_Index 
    COMMIT
END
要避免我的DequeueRelevantSRPs存储过程试图删除一个已选定的锁定行(并且失败),最好的做法是使用SRPQueue.Status变量吗

这将很好,因为我可以有一些不同的状态(挂起、处理、就绪、失败),我只需要一个额外的和SRPQueue.Status='ready'检查。是否有另一种方法可以确保删除成功,尽管它可能被锁定


编辑:调用这些存储过程的应用程序将在多个服务器上的多个实例中运行。这是一个重要的细节,Insert、Update和Delete指令锁定事务中的表,Select Wait for Tables unlocked(选择等待表解锁)

我将在没有TRAN的情况下进行第一次SP

ALTER PROCEDURE [dbo].[GetSRPsToProcess]
    @CurrentTime DateTime
AS
BEGIN

        Select TOP 20 *
        From SRPQueue WITH (updlock, ROWLOCK, readpast)
        WHERE SRPQueue.TimeToDequeue <= @CurrentTime AND SRPQueue.Status = 'Pending'
        ORDER BY SRPQueue_Index 

END
ALTER过程[dbo]。[GetSRPsToProcess]
@当前时间日期时间
像
开始
选择前20名*
来自SRPQUE,带有(updlock、ROWLOCK、readpast)

其中SRPQueue.TimeToDequeue插入、更新和删除指令锁定事务中的表,选择等待表解锁

我将在没有TRAN的情况下进行第一次SP

ALTER PROCEDURE [dbo].[GetSRPsToProcess]
    @CurrentTime DateTime
AS
BEGIN

        Select TOP 20 *
        From SRPQueue WITH (updlock, ROWLOCK, readpast)
        WHERE SRPQueue.TimeToDequeue <= @CurrentTime AND SRPQueue.Status = 'Pending'
        ORDER BY SRPQueue_Index 

END
ALTER过程[dbo]。[GetSRPsToProcess]
@当前时间日期时间
像
开始
选择前20名*
来自SRPQUE,带有(updlock、ROWLOCK、readpast)

在SRPQueue.TimeToDequeue中,我不确定第一个存储过程是否会在
SELECT
语句期间维护它所获取的锁。至少在DB2中,锁通常在
提交时释放。。。您可能希望将提交级别拉到更高的级别,但如果这些级别在同一线程中运行,我认为无论如何都允许
删除
。您要么需要维护锁(并让其他语句跳过锁),要么将一行标记为正在处理,将其解锁,并告诉其他语句忽略标记的行。Derp,我忘了澄清调用这些存储过程的应用程序将在多个服务器上具有多个实例,这会大大改变动态……尤其是在这种情况下,您可能希望将正在运行(处理)的作业“注册”到系统中,按作业标记签出,然后设置某种监视作业,以提醒操作员/取消注册其中一个作业,如果其中一个作业在一段时间内没有执行任何操作。否则,您可能需要整个事务的总体事务(而不是每个语句)。虽然我不确定是
Top20
只锁定“Top20”行还是整个集合(可能取决于该列上是否有索引),或者,这对尝试插入
更高的行有什么影响。仅仅通过在选择行的同一事务中更新队列状态,然后在删除中检查所述更新状态,是否可以缓解该过程?请注意,是否有任何方法可以同时进行选择和更新(可能通过使用输出)?至于后半部分,我认为rowlock、updatelock和readpass应该确保只锁定前20行,而不是锁定整个集合。否则,我对它们如何工作的理解就有相当大的缺陷=/。DB2至少支持“数据更改表引用”,这意味着您可以执行类似于
从新表中选择(INSERT…
)的操作,并获取新行。这类内容是特定于实现的,但我想我看到一些版本的SQL Server具有类似的语法。哦,我假设您只想删除特定作业正在运行的那些行。呃,我不确定第一个存储过程是否会在
SELECT
语句中维护它所获取的锁。至少在DB2中,锁通常在
提交时释放。。。您可能希望将提交级别拉到更高的级别,但如果这些级别在同一线程中运行,我认为无论如何都允许
删除
。您要么需要维护锁(并让其他语句跳过锁),要么将一行标记为正在处理,将其解锁,并告诉其他语句忽略标记的行。Derp,我忘了澄清调用这些存储过程的应用程序将在多个服务器上具有多个实例,这会大大改变动态……尤其是在这种情况下,您可能希望将正在运行(处理)的作业“注册”到系统中,按作业标记签出,然后设置某种监视作业,以提醒操作员/取消注册其中一个作业,如果其中一个作业在一段时间内没有执行任何操作。否则,您可能需要整个事务的总体事务(而不是每个语句)。虽然我不确定是
Top20
只锁定“Top20”行还是整个集合(可能取决于该列上是否有索引),或者,这对尝试插入
更高的行有什么影响。仅仅通过在选择行的同一事务中更新队列状态,然后在删除中检查所述更新状态,是否可以缓解该过程?请注意,是否有任何方法可以同时进行选择和更新(可能通过使用输出)?至于后半部分,我认为rowlock、updatelock和readpass应该确保只锁定前20行,而不是锁定整个集合。否则,我对它们如何工作的理解就有相当大的缺陷=/。DB2至少支持“数据更改表引用”,这意味着您可以执行类似于
从新表中选择(INSERT…
)的操作,并获取新行。这类内容是特定于实现的,但我想我看到一些版本的SQL Server具有类似的语法。哦,我假设你只想删除那些