2

私はEntityFrameworkで遊んでいますが、これまでのところ、EntityFrameworkをよく使用しています。しかし、これまでに行ったことはすべて、ほとんどの場合にうまく機能する楽観的なロックを前提としています。ただし、次のシナリオがあります。

  1. アプリケーション全体のデータを保持する1行のみのSQLServerテーブル
  2. 行には「NextAvailableNumber」という名前の列が含まれています
  3. アプリケーションは、数値を読み取り、1ずつインクリメントして、更新する必要があります

上記は、競合するプロセスが最初のトランザクションが完了するまで番号を取得するのを待たなければならないことを保証する必要があります。以前はテーブルロックを使用してこれを実行していましたが(行が1つしかないため)、LINQ to Entitiesを使用してこれを実行する方法を知りたいですか?

ありがとう、

ジムK。

4

3 に答える 3

1

明示的な行ロック(または前述のようにテーブルロック)を使用するため、これをストアドプロシージャに実装する必要があると思います。次に、EFからそのプロシージャを呼び出します。特別なテーブルで作業するたびにシリアル化可能なトランザクションを使用しない限り、これをアプリケーションコードから処理できるとは思いません。アプリケーションのパフォーマンスに大きな悪影響を与える可能性があります。

私たちは実際に似たようなことをしていますが、テーブルにはさまざまなシーケンスの行がたくさん含まれているため、行ロックと更新ロックを備えたストアドプロシージャを使用しています。最初はリポジトリのinsertメソッドでこのプロシージャを呼び出したかったのですが、その後データベースに移動し、挿入トリガーの後でプロシージャを呼び出しました。この理由は、EFコンテキストでの挿入のためにエンティティをマークする時間ではなく、データベースへの実際の挿入の時間に行ロックを延期するためでした(この場合、挿入自体とプロシージャ呼び出しは同じトランザクション内にある必要があります)。関連するプロパティでStoreGeneratedPatternが計算に設定されるようにEFモデルを変更しました。挿入するたびに、EFはDBを再クエリして、割り当てられたシーケンス番号を取得します。唯一の欠点は、EFがこれらのエンティティを更新するたびにDBを再クエリすることですが、この場合、タイムスタンプのためにすでにこれを実行しています。これはまだテストと評価の段階にあるので、考えを変えて再実装することができます。

于 2011-02-06T00:38:16.627 に答える
1

私たちが使用している別の解決策があり、特に私たちのようにEFコードファーストを使用している場合は、ストアドプロシージャの使用を回避するために使用できます。Code Firstは、ストアドプロシージャの使用をサポートしていません。

解決策は、トランザクションのスコープ内でEFのSqlQueryメソッドを使用することです。最初に次の数値カウンターの更新を実行し、次にそれを選択するクエリを作成する必要があります。コードは次のようになります。

string query = "UPDATE Registre_Counter SET Counter = Counter + 1 WHERE CounterName = @p0 AND Year = @p1;";
query += "select * from Registre_Counter Where CounterName = @p0 AND Year = @p1";

GenericCounter GenericCounter = CoreDBContext.Instance().GenericCounter.SqlQuery(query, new Object[] { _counterName, _year }).SingleOrDefault(); //Updates the counter and return de NextNumber to Use

Updateはカウンターをロックし、トランザクションが中止またはコミットされるまで、カウンター上の他のトランザクションからの読み取りを回避します。

于 2011-06-01T08:09:30.997 に答える
0

Entity Frameworkは楽観的ロックを使用しているため、次の番号が2番目のプロセスによって変更されると、例外がスローされます。この状況に対抗する最も原始的な方法は、例外をキャッチし、変更が成功するまで変更をやり直すことです。[これにタイムアウトを追加して、最悪のシナリオでコードの実行が確実に進むようにすることができます]

于 2011-02-05T18:02:47.557 に答える