0

バックエンドとして sql データベースを使用して単純なキューを作成したいと考えています。テーブルには、id、タスク名、runat(datetime)、hidden(datetime) のフィールドがあります。

キュー アイテムが 1 回だけ実行されないようにしたい。

アイデアは、クライアントがデキューしたいときに、ストアド プロシージャが最初のアイテム (runat および hidden < now でソート) を選択し、非表示フィールドを現在の時間 + 2min に設定して、アイテムを返すことです。

MS Sql (正確には Azure) wokr はどのように機能しますか? または、それらが1つずつ実行され、2番目のフィールドが最初のフィールドで非表示フィールドが変更されたのと同じアイテムを返さないことを確認できますか?

4

2 に答える 2

3

重要なのは、受信しているキュー アイテムのロック (行またはテーブル) を取得することです。いくつかの方法を使用できますが、私のお気に入りは OUTPUT 句を使用した UPDATE です。どちらも、テーブルへのシリアル化されたアクセスを生成します。

例:

CREATE PROCEDURE spGetNextItem_output
BEGIN
    BEGIN TRAN

    UPDATE TOP(1) Messages
    SET [Status] = 1
    OUTPUT INSERTED.MessageID, INSERTED.Data
    WHERE [Status] = 0

    COMMIT TRAN
END

CREATE PROCEDURE spGetNextItem_tablockx
BEGIN
    BEGIN TRAN

    DECLARE @MessageID int, @data xml

    SELECT TOP(1) @MessageID = MessageID, @Data = Data
    FROM Messages WITH (ROWLOCK, XLOCK, READPAST) --lock the row, skip other locked rows
    WHERE [Status] = 0

    UPDATE Messages
    SET [Status] = 1
    WHERE MessageID = @MessageID

    SELECT @MessageID AS MessageID, @Data as Data

    COMMIT TRAN
END

テーブル定義:

CREATE TABLE [dbo].[Messages](
    [MessageID] [int] IDENTITY(1,1) NOT NULL,
    [Status] [int] NOT NULL,
    [Data] [xml] NOT NULL,
     CONSTRAINT [PK_Messages] PRIMARY KEY CLUSTERED 
    (
        [MessageID] ASC
    )
) 
于 2012-10-06T21:46:04.560 に答える
0

Windows Azure SQLデータベースは、同時実行性の点でSQLServerデータベースと同じように動作します。これはデータベースの問題であり、WindowsAzureの問題ではありません。

現在:独自のキューを実装するのではなく、Windows Azureキュー(またはサービスバスキュー)を使用した場合、動作は十分に文書化されています。たとえば、Azure Queuesでは、first-inがキューアイテムを取得し、アイテムが削除されるかタイムアウト期間に達するまで、アイテムは非表示としてマークされます。

于 2012-10-06T18:33:15.580 に答える