如何修改SQL Server队列查询代码 每次锁定读取25条记录避免多实例抢占
SQL Server 数据表队列改造问题解答
1. 每次处理25条记录的修改方案
你可以用表变量存储批量选中的待处理ID,保留原有的UPDLOCK、READPAST锁提示保证并发安全(三个控制台应用不会抢到同一条记录),修改后的代码如下:
DECLARE @SelectedIDs TABLE (ID INTEGER) BEGIN TRANSACTION -- 批量选中25条待处理记录,存入表变量 SELECT TOP 25 ID INTO @SelectedIDs FROM MyQueueTable WITH (UPDLOCK, READPAST) WHERE StateField = 0 ORDER BY ID ASC -- 批量标记为处理中 IF EXISTS (SELECT 1 FROM @SelectedIDs) UPDATE m SET Status = 1 FROM MyQueueTable m INNER JOIN @SelectedIDs s ON m.ID = s.ID COMMIT TRANSACTION -- 返回选中的完整记录给调用端 IF EXISTS (SELECT 1 FROM @SelectedIDs) SELECT * FROM MyQueueTable m INNER JOIN @SelectedIDs s ON m.ID = s.ID
这个改造完全兼容你现有多实例并发处理的需求,READPAST会让其他会话直接跳过已经被加锁的记录,不会出现抢同一条数据的情况。
2. 末尾SELECT语句的作用
末尾的SELECT是必须存在的,用途如下:
- 第一段的SELECT只是数据库内部的赋值操作,只会把ID值存到变量里,不会把查询结果返回给调用你的控制台应用
- 末尾的SELECT才会把已经标记为处理中的完整记录数据返回给应用层,你的控制台程序才能拿到记录的具体字段内容执行业务逻辑
- 如果去掉这一段,应用只能知道有没有抢到待处理记录,无法拿到记录的具体信息,没法做后续处理。
内容的提问来源于stack exchange,提问作者Mist
相关产品推荐
相关产品推荐

