這就是我已經在過去成功應用於:
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