1

我创建了一个系统,每天通过 SMS 向我们的客户发送一些信息。因为发送 SMS 的过程可能需要一段时间,这是由多个进程完成的,每个进程发送有限数量的 SMS。当一个进程读取许多 pohne nubers 的记录(比如说 1000 个)来发送短信时。我想标记这 1000 条记录,其他进程也不会读取这些记录。

Select Top(1000) ID, Number from Phones where isactive = 1 and isverified = 1

我需要一些代码来做这样的事情:

update Phones, set ReadTime = getdate() where(以上选择)

现在我想更新ReadTime这些记录的列getdate()以确保其他调度进程不会再次读取它们(我设置日期时间标志而不是位标志的原因是某些 SMS 发送可能会失败,这样我能看懂哪些是很久以前读过但没有更新发送时间的)

在发送短信后标记它们(无论如何都应该写发送时间)将无济于事,因为将处理发送短信的预定任务将一次读取所有 1000 条记录,并且可能会有其他进程读取的记录但尚未标记(因为尚未发送 SMS)。

4

3 回答 3

3

你应该能够做这样的事情:

UPDATE Phones
SET ReadTime = GetDate()
WHERE ID IN (SELECT Top 1000 ID
             FROM Phones
             WHERE IsActive = 1
                 AND IsVerified = 1
                 AND ReadTime Is Null -- you will want to exclude any records already updated
             ORDER BY ID) 

SQL Fiddle with Demo

于 2012-09-08T16:33:41.593 回答
1

您可以在表中添加一个额外的列,该列采用进程 ID 的 id。然后你可以在每个进程中调用:

UPDATE Phones
SET ReadTime = GetDate(),
ProcessId = "Process0001" --or whatever the process ID is
WHERE ID IN (SELECT Top 1000 ID FROM Phones WHERE IsActive = 1 AND IsVerified = 1
                 AND ProcessId IS NULL AND ReadTime IS NULL) 

然后,您使用您的进程 ID 调用所有记录。最后,您从表中删除进程 ID。

于 2012-09-08T16:45:06.667 回答
1

您可以一次选择并输出行。这将确保选择的行与更新的行相同,选择的答案会失败。

;with a
as
(
select top 1000 readtime, id, number from @phones 
where isactive = 1 and isverified = 1 
and readtime is null
)
update a
set Readtime = getdate()
output deleted.ID, deleted.Number
于 2012-09-09T06:29:12.833 回答