我们正在尝试从表中检索和更新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
我们非常感谢您的帮助。非常感谢!
答案 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并发性和隔离性之前先对其进行很好的阅读。