sql - 使用数据库表作为队列

标签 sql database sql-server-2008 queue

我想使用数据库表作为队列。我想插入其中并按插入顺序(FIFO)从中获取元素。我主要考虑的是性能,因为我每秒有数千个这样的交易。所以我想使用一个 SQL 查询,它可以在不搜索整个表的情况下为我提供第一个元素。阅读时我不会删除一行。 SELECT TOP 1 ..... 在这里有帮助吗? 我应该使用任何特殊索引吗?

最佳答案

我会使用一个 IDENTITY 字段作为主键,为每个排队的项目提供唯一递增的 ID,并在其上粘贴一个聚集索引。这将表示项目排队的顺序。

要在处理项目时将项目保留在队列表中,您需要一个“状态”字段来指示特定项目的当前状态(例如 0=等待,1=正在处理,2=已处理)。这是防止一个项目被处理两次所必需的。

当处理队列中的项目时,您需要找到表中当前未处理的下一个项目。这需要以这样一种方式进行,以防止多个进程同时拾取同一项目进行处理,如下所示。注意 table hints UPDLOCK 和 READPAST 在实现队列时应该注意。

例如在存储过程中,像这样:

DECLARE @NextID INTEGER

BEGIN TRANSACTION

-- Find the next queued item that is waiting to be processed
SELECT TOP 1 @NextID = ID
FROM MyQueueTable WITH (UPDLOCK, READPAST)
WHERE StateField = 0
ORDER BY ID ASC

-- if we've found one, mark it as being processed
IF @NextId IS NOT NULL
    UPDATE MyQueueTable SET Status = 1 WHERE ID = @NextId

COMMIT TRANSACTION

-- If we've got an item from the queue, return to whatever is going to process it
IF @NextId IS NOT NULL
    SELECT * FROM MyQueueTable WHERE ID = @NextID

如果处理一个项目失败,你想稍后再试吗?如果是这样,您需要将状态重置为 0 或其他内容。这将需要更多思考。

或者,不要将数据库表用作队列,而是使用 MSMQ 之类的东西 - 我只是想把它混在一起!

关于sql - 使用数据库表作为队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2177880/

相关文章:

java - 如何在java中获取按日期的销售情况?

sql - 按邮政编码邻近度搜索 - MySql

javascript - 在 Sequelize 中定义模型的不同方式

在 SQL Server 2008 上创建表的 SQL 注释

sql - Postgresql 将两个表的 SUM 值与相同的列组合在一起

sql - 为什么必须对 CASE 语句中的列进行 GROUP BY?

sql - 如何建立从本地到 SQL Azure 数据库的安全连接字符串

sql - 在联接表中计数的最佳方法

sql - 是否可以使用 CTE 将列值连接成字符串?

sql - 将 SQL Server 连接限制为特定 IP 地址