5

さまざまなスレッドがリストからエンティティを取得し、ステータスを設定して、それらのアイテムで処理が開始されたという事実をマークする、軽量のキュー処理を実装する S#arp アーキテクチャ アプリがあります。

明示的なトランザクションで開始処理ビットをラップし、C# の lock() を使用しているにもかかわらず、それらが同時に開始されることがあります。

MSMQ を使用しなかったことを後悔していますか ... そうですね。しかし、この同時実行動作には困惑しています。明らかに、NHibernate のトランザクションとフラッシュについて理解できないことがあります。あなたは私を助けることができます?

関連するコードは次のとおりです。

private static object m_lock = new object();

private bool AbleToStartProcessing(int thingId)
{
    bool able = false;
    try
    {
        lock (m_lock)
        {
            this.thingRepository.DbContext.BeginTransaction();
            var thing = this.thingRepository.Get(thingId);
            if (thing.Status == ThingStatusEnum.PreProcessing)
            {
                able = true;
                thing.Status = ThingStatusEnum.Processing;
            }
            else
            {
                logger.DebugFormat("Not able to start processing {0} because status is {1}",
                        thingId, thing.Status.ToString());
            }
            this.thingRepository.DbContext.CommitTransaction();
        }
    }
    catch (Exception ex)
    {
        this.thingRepository.DbContext.RollbackTransaction();
        throw ex;
    }
    if (able)
        logger.DebugFormat("Starting processing of {0}",
                        thingId);
    return able;
}

これにより、一度に 1 つのスレッドだけが「もの」のステータスを変更できることが保証されると期待していましたが、ログにはかなり定期的にこれが記録されています。

2011-05-18 18:41:23,557 thread41 DEBUG src:MyApp.Blah.ThingJob - Starting processing of 78090
2011-05-18 18:41:23,557 thread51 DEBUG src:MyApp.Blah.ThingJob - Starting processing of 78090

..そして、両方のスレッドが同じことを試みて操作し、混乱を引き起こします。

私は何が欠けていますか?ありがとう。

編集:実際のバージョンでログがどのように機能するかを反映するようにコードを変更しました

4

2 に答える 2

1

NHibernate マッピングで同時実行をセットアップします。この投稿は、開始するのに役立ちます。

http://ayende.com/blog/3946/nhibernate-mapping-concurrency

于 2011-05-23T17:06:21.357 に答える
0

処理中であることを設定し、すでに処理中であることを確認するために使用しているステータスについて、あなたは混乱していると思います。セット ThingStatusEnum.Processing の最初の 1 つですが、次の人は別のものをチェックしています - ThingStatusEnum.PreProcessing。ThingStatusEnum.Processing != ThingStatusEnum.PreProcessing であるため、ロックは 2 つのスレッドが存在しないことを意味します。

于 2011-05-23T17:13:00.680 に答える