0

ワーカー プロセスのプールによって処理される長時間実行されるユーザー操作があります。データの入出力は Azure SQL から行われます。

マスター Azure SQL テーブル構造の列は次のように近似されます

[UserId, col1, col2, ... , col N, beingProcessed, lastTimeProcessed ] 

beingProcessedブール値で、lastTimeProcessedDateTime です。すべてのワーカー ロールのロジックは以下に示すとおりであり、複数のワーカー処理 (それぞれが独自の Entity Framework レイヤーを使用) を使用して、本質的beingProcessedに MutEx の目的でロックを使用しています。

質問beingProcessed:上記の負荷に基づいて、「ロック」自体の同時実行の問題にどのように対処できますか? read-modify-writeニーズに対する操作はbeingProcessedアトミックである必要があると思います が、他の戦略にもオープンです。他のコードの改良も可能です。

[更新]: ここで何が必要なのだろうかTransactionScope... http://msdn.microsoft.com/en-US/library/system.transactions.transactionscope(v=vs.110).aspx

コード:

public void WorkerRoleMain()
{
    while(true)
    {
        try
        {
            dbContext db = new dbContext();

            // Read
            foreach (UserProfile user in db.UserProfile
                    .Where(u => DateTime.UtcNow.Subtract(u.lastTimeProcessed) 
                            > TimeSpan.FromHours(24) & 
                            u.beingProcessed == false))
            {
                user.beingProcessed = true; // Modify
                db.SaveChanges();           // Write
                // Do some long drawn processing here
                ...
                ...
                ...
                user.lastTimeProcessed = DateTime.UtcNow;
                user.beingProcessed = false;
                db.SaveChanges();
            }
        }
        catch(Exception ex)
        {
            LogException(ex);
            Sleep(TimeSpan.FromMinutes(5));
        }
    } // while ()
}
4

1 に答える 1

0

私たちが通常行うことは次のとおりです。

長い操作の開始時に、トランザクションを開始します。

BEGIN TRANSACTION

次に、これらのヒントを使用して更新/削除するテーブルから行を選択します。

SELECT * FROM Table WITH (ROWLOCK, NOWAIT) Where ID = 123;

次に、行があることを確認します。行が別のプロセスによってロックされている場合、SQL エラーが発生します。この場合、トランザクションをロールバックし、ユーザーに通知します。レコードがロックされている場合、レコードを処理し、レコードのロックに使用したのと同じトランザクション オブジェクトを使用して、必要な更新を行います。

UPDATE Table SET Col1='value' WHERE ID = 123;

次に、トランザクションを COMMIT します。

COMMIT;

これは、プロセスの単なる擬似コードです。プログラムに実装する必要があります。

上記のプロセスに関する小さなメモ。SQL Server (または Azure) でレコードをロックするときは、WHERE 句で主キーを使用します。そうしないと、SQL Server はページ ロックまたはテーブル ロックの使用を決定します。

于 2012-12-13T00:19:26.227 に答える