如何修复“ UPDATE <table> OUTPUT WITH(READPAST)”

时间:2019-08-02 10:41:34

标签: sql sql-server tsql sql-update

我们正在尝试从表中检索和更新TOP X事件,但没有锁定“已处理”行以外的任何内容。我们研究了不同的SQL提示,例如ROWLOCK和READPAST,但还没有弄清楚在这种情况下应使用哪种提示。另外,我们需要确保返回的行在该查询的不同并发执行中是唯一的,并且同一行永远不会被选择两次。

注意:该表有许多INSERT同时发生。

UPDATE TOP(:batchSize) wsns WITH (READPAST) 
 SET consumer_ip = :consumerIP 
 OUTPUT inserted.id, inserted.another_id, inserted.created_time, inserted.scheduled_time 
 FROM table_A a
 WHERE a.scheduled_time < GETUTCDATE() AND a.consumer_ip IS NULL

我们非常感谢您的帮助。非常感谢!

1 个答案:

答案 0 :(得分:1)

我不太了解您为什么/为什么尝试在此处使用READPAST提示? 但是无论如何-要实现您想要的目标,我建议:

WITH xxx AS
(
SELECT TOP(:batchSize) * 
FROM table_A
)
UPDATE xxx
SET consumer_ip = :consumerIP 
OUTPUT inserted.id, inserted.another_id, inserted.created_time, inserted.scheduled_time 
FROM table_A a
WHERE a.scheduled_time < GETUTCDATE() AND a.consumer_ip IS NULL;

如果所有可能在后台发生的都是新插入,那么我看不出为什么会出现问题。 SQL Server优化程序很可能会决定使用PAGE / ROW锁定(但这取决于您的数据库设置以及受影响的索引及其选项)。如果出于某种原因您想在此更新完成之前停止其他事务-在整个表上持有排他锁,直到事务结束,您只需添加WITH(TABLOCKX)。因此,强烈建议您在生产环境中开始使用SQL Server并发性和隔离性之前先对其进行很好的阅读。