这就是我已经在过去成功应用于:
MsgQueue表模式
MsgId identity -- NOT NULL
MsgTypeCode varchar(20) -- NOT NULL
SourceCode varchar(20) -- process inserting the message -- NULLable
State char(1) -- 'N'ew if queued, 'A'(ctive) if processing, 'C'ompleted, default 'N' -- NOT NULL
CreateTime datetime -- default GETDATE() -- NOT NULL
Msg varchar(255) -- NULLable
你的消息类型你所期望 - 符合流程插入和流程读取之间契约的消息,使用XML或您的其他表示形式(例如,在某些情况下JSON会很方便)构建。
然后可以插入0到n个进程,并且0到n个进程可以读取和处理消息。每个读取进程通常处理单个消息类型。可以运行多个进程类型的实例来进行负载平衡。
阅读器读取一条消息,并在其工作时将状态更改为“A”。完成后,它将状态更改为“C”完成。它可以删除或不删除,具体取决于您是否要保留审计线索。 State ='N'的消息以MsgType/Timestamp顺序拉取,因此在MsgType + State + CreateTime上有一个索引。
变化:
状态为“E”rror。
读取器进程代码的列。
状态转换的时间戳。
这提供了一个很好的,可扩展的,可见的,简单的机制来完成许多事情,比如你所描述的。如果你对数据库有一个基本的了解,那么它是非常简单和可扩展的。从评论
代码:
CREATE PROCEDURE GetMessage @MsgType VARCHAR(8))
AS
DECLARE @MsgId INT
BEGIN TRAN
SELECT TOP 1 @MsgId = MsgId
FROM MsgQueue
WHERE MessageType = @pMessageType AND State = 'N'
ORDER BY CreateTime
IF @MsgId IS NOT NULL
BEGIN
UPDATE MsgQueue
SET State = 'A'
WHERE MsgId = @MsgId
SELECT MsgId, Msg
FROM MsgQueue
WHERE MsgId = @MsgId
END
ELSE
BEGIN
SELECT MsgId = NULL, Msg = NULL
END
COMMIT TRAN
Right - bad =同步IPC,在dbms上作为一个读作为SELECT进行阻塞。你大概是在做这个引入异步性的策略。 – dkretz 2008-11-18 00:21:59
顺便说一句,如果你想把阅读器放在定时器上,让它们不频繁检查是很有用的,但是如果它们找到工作,它们可以在再次睡觉之前排空队列。 – dkretz 2008-11-18 00:23:31
请注意我的编辑:如果他们找不到工作,他们将永远找不到工作。但是,如果这不是真的...... – BCS 2008-11-18 00:26:23