如何锁定正在执行的存储过程并更改存储过程返回的表?

Posted

技术标签:

【中文标题】如何锁定正在执行的存储过程并更改存储过程返回的表?【英文标题】:How would I lock a stored procedure that is executing and alter the table that the stored procedure returns? 【发布时间】:2019-06-17 06:57:53 【问题描述】:

我有一张如下表:

id    status
--    ------
1     pass
1     fail
1     pass
1     na
1     na

另外,我有一个存储过程,它返回一个表,其中前 100 条记录的状态为“na”。存储过程可以由环境中的多个节点调用,我不希望它们获取重复数据。所以,我想在存储过程执行时锁定存储过程,并将从存储过程获取的记录的状态设置为“进行中”并返回该表然后释放锁,这样不同的节点就不会获取相同的数据。我将如何做到这一点?

【问题讨论】:

【参考方案1】:

您可以将 select 与 WITH (SERIALIZABLE) 隔离级别一起使用,以确保记录被锁定,直到状态更新如下。

SELECT TOP 100 id 
INTO   #temp 
FROM   [your_table] WITH (serializable) 
WHERE  status = 'na' 

UPDATE ut 
SET    status = 'In Progress' 
FROM   [your_table] ut WITH (serializable) 
       INNER JOIN #temp T 
               ON T.id = ut.id 

SERIALIZABLE 隔离级别指定以下内容:

语句无法读取已修改但尚未修改的数据 由其他事务提交。 没有其他事务可以修改已由 当前事务直到当前事务完成。 其他事务不能插入带有键值的新行 落在当前任何语句读取的键范围内 交易直到当前交易完成。

Source (MSDN)

【讨论】:

更新 ut...这里有什么? ut 是用于更新的表的别名。 如果有两个表,我应该使用“from table1, table2 with serializable”吗?如果从两个表中获取记录,那么应用相同格式是正确的格式吗 来自 table1 WITH (serializable) , table2 WITH (serializable) 。更好地使用连接

以上是关于如何锁定正在执行的存储过程并更改存储过程返回的表?的主要内容,如果未能解决你的问题,请参考以下文章

如何暂停存储过程一段时间?

SQL SERVER里面如何在存储过程里面获取另一个存储过程所返回的表的数据?

SQL SERVER里面如何在存储过程里面获取另一个存储过程所返回的表的数据?

如何使用c#执行返回多个游标的oracle存储过程

在 PHP 中插入和从存储过程中选择

如何在sql server的另一个存储过程中执行存储过程