69

Entity Framework(4.1)を使用してアクセスするSQL Server(2012)があります。データベースには、独立したプロセスが新しいURLをフィードするURLというテーブルがあります。URLテーブルのエントリは、「新規」、「処理中」、または「処理済み」の状態にすることができます。

別のコンピューターからURLテーブルにアクセスし、ステータスが「新規」のURLエントリを確認し、最初のエントリを取得して「処理中」としてマークする必要があります。

var newUrl = dbEntity.URLs.FirstOrDefault(url => url.StatusID == (int) URLStatus.New);
if(newUrl != null)
{
    newUrl.StatusID = (int) URLStatus.InProcess;
    dbEntity.SaveChanges();
}
//Process the URL

クエリと更新はアトミックではないため、2台の異なるコンピューターでデータベース内の同じURLエントリを読み取って更新することができます。

このような衝突を回避するために、select-then-updateシーケンスをアトミックにする方法はありますか?

4

4 に答える 4

1

UPDLOCK ヒントをデータベースに渡して、特定の行をロックすることもできます。そのため、更新するために選択したものも排他ロックを取得して、変更を保存できます (最初に読み取りロックを取得するのではなく、 later は後で保存時にアップグレードを試みます)。上記のjocullによって提案されたHoldlockも良い考えです。

private static TestEntity GetFirstEntity(Context context) {
return context.TestEntities
          .SqlQuery("SELECT TOP 1 Id, Value FROM TestEntities WITH (UPDLOCK)")
          .Single();
}

オプティミスティック コンカレンシーを検討することを強くお勧めします: https://www.entityframeworktutorial.net/EntityFramework5/handle-concurrency-in-entity-framework.aspx

于 2019-07-22T11:40:49.527 に答える