2

ExperimentEntity Framework 4.0 を使用して、SQL Server データベースにnew を挿入するとします。

  • Experimentその中に 1..*Tasksがあります
  • との両方ExperimentからTask派生EntityObject
  • また、それぞれにリンクされたTask「親」が 1 つだけ必要であるというデータベースの制約があります。Experiment

挿入はアトミックでなければなりません。アトミックとは、データベースのリーダーがデータベースExperimentに完全に書き込まれていないもの、たとえばExperimentwith noを読み取ってはならないということTaskです。

これまでに試したすべてのソリューションには、数秒しか続かないにもかかわらず、一部の不完全な実験を読み取ることができるという問題があります。つまり、実験は最終的にそのタスクを迅速に取り込まれますが、原子的にではありません。

すなわち、

  • 私のreader.exeは、while(true)すべての実験をループで読み取り、タスクのない実験をダンプします。
  • 並行してwriter.exe、すべて 1 つのタスクで ~1000 の実験を 1 つずつ書き、データベースに保存します。

不完全な実験を読まないようにReadAllExperimentsand関数を書く方法を見つけることができません。WriteOneExperiment

どうすればいいですか?

PS:

私はデータベースの初心者です。書き込み時にシリアル化可能な分離レベルでトランザクションを試したり、UPDLOCK を使用して読み取りを手動で SQL 要求したりしましたが、この問題の解決に成功しなかったため、行き詰まっています。

私が非常に基本的で簡単なニーズだと思っていたものが、不適切な問題であることが明らかになるでしょうか?

問題はここで単体テストされます: Entity Framework Code First: SaveChanges はアトミックではありません

4

2 に答える 2

1

以下は、READ UNCOMMITTEDまたは同様の分離レベルで読んでいないと仮定した後、実際に実行する必要があります

using(var ctx = new MyContext())
{
    var task = new Task{};
    ctx.Tasks.Add(task);
    ctx.Experiment.Add(new Experiment{ Task = task });
    ctx.SaveChanges();
}

この場合、READ UNCOMMITTED または同様のものを使用している場合、実験が追加される前にタスクが表示されます。説明した制約が与えられた場合、タスクの前に実験が存在できる状態になることはないと思います。

于 2013-06-07T12:42:17.787 に答える
1

2つの解決策は明らかに私たちの問題を解決します。

  1. データベース オプション "Is Read Committed Snapshot On" = True (デフォルトでは、False です)
  2. データベース オプション「スナップショット分離を許可」=True + スナップショット分離レベルを使用して読み取りを実行。以前にスナップショット分離を使用して読み取りを試みましたが、この db オプションについて知りませんでした。無効な分離レベルで読み取るときにエラーが発生しない理由はまだわかりませんか?

詳細については、http://www.codinghorror.com/blog/2008/08/deadlocked.html または

MSDN: http://msdn.microsoft.com/en-us/library/ms173763.aspx (READ_COMMITTED_SNAPSHOT を検索)

http://msdn.microsoft.com/en-us/library/ms179599%28v=sql.105%29.aspx

于 2013-06-11T06:53:43.557 に答える