I.はじめに
まず私たちは、同時実行の競合が何であるかを見てみましょう。
競合が同時にデータテーブルを変更するような、同時に、アクションを実行する、いわゆる複数のスレッドによって複雑にされ、データの変更にリードを適切に保存することはできません。
悲観的同時実行とオプティミスティック同時:同時実行が分かれています
ペシミスティック同時実行:2つのスレッドが、データベースの同じテーブルを修正する修正Aを入力し、Bを変更することはできません、変更のみを入力するように、完全な変更AのためにBを待つことができます。
オプティミスティック同時実行:Bは、[保存彼のA保存し、データベースレコードと矛盾していることをシステムが検出するだけでBに入った後に保存するとき、Bが例外をスローします修正、変更が失敗した場合、AはBにも変更することができます修正しました。
基本的な開始点は、オプティミスティック同時実行です:セーブデータは楽観的な態度を保持する場合、紛争の同時イベントは、だけでなく、違反の例外をキャプチャし、ポリシーに基づいて競合を解決する場合でも、同時競合を発生することが予想されていません。
EFは、我々は、データ処理に特別な注意を払うようにすることで、楽観的並行性を使用しています。
一例として、私自身の経験を次の質問。
二、シーン
私のプロジェクトでは、それは残念ながら同じ操作をシミュレートしたデータの存在が正常に動作することが可能であるそのうちの一つ、二回であり、そこに機能、データを削除するには、まず、追加データがあり、その後、この機能を使用するために二回シミュレートしたが別の書き込みデータの前に削除されますので、私は並行性競合が削除されたと思う二度目になります。
调用的时候出现这个错:データベース操作が1行(複数可)が、実際に影響を受ける0の行(複数可)に影響することが期待。エンティティがロードされたため、データが変更または削除された可能性があります。理解し、オプティミスティック同時実行例外の処理については、http://go.microsoft.com/fwlink/?LinkId=527962を参照してください。
公式サイト与えられたソリューションがDbUpdateConcurrencyException例外を捕捉することによって解決され、以下の公式サイト与えられた例であります
公式サイト:https://docs.microsoft.com/zh-cn/ef/core/saving/concurrency
(VARコンテキスト=新しいPersonContext())を使用して { //データベースと変更電話番号から人物を取得 するvar人物= context.People.Single(P => p.PersonId == 1)。 person.PhoneNumber = "555-555-5555"。 並行性競合シミュレートするために、データベース内の//変更した人の名前 context.Database.ExecuteSqlRaw( 「PERSONID = 1 UPDATE dbo.People SET姓= 'ジェーン」)を、 varが= falseを保存しました。 (!保存)しながら、 { しようと { //データベースへの変更保存しよう context.SaveChangesを(); 保存された=真; } キャッチ(DbUpdateConcurrencyException EX) { foreachの(ex.EntriesにおけるVARエントリー) { (entry.Entityが人である)なら 、{ VAR proposedValues = entry.CurrentValues。//当前值 VAR databaseValues = entry.GetDatabaseValues(); //数据库中的值 のforeach(proposedValues.PropertiesにおけるVARプロパティ) { VAR proposedValue = proposedValues [プロパティ]。 VAR databaseValue = databaseValues [プロパティ]。 // TODO:データベースに書き込まれるべき値を決めます // proposedValues [プロパティ] = <値を保存します>。 } チェックバイパスオリジナル//次の同時実行に値を更新し entry.OriginalValues.SetValues(databaseValues); //元のデータ内のメモリにデータベースの値を更新し、疑わしいがあるかもしれません、理由は現在の値にあなたと一緒に行きません保存されたOriginalValuesは元の値、すべての修正前のデータであるため、 } 他 { 非サポート例外が新新(スロー 「どのように並行性の競合のために知っていないを処理するためには、」 ; + entry.Metadata.Nameを) } } } } }
私は別の方法を使用してGetDatabaseValuesは、空として表示されますので、私の操作は、データの削除を含むので、自分の状況に応じて変換するには
= falseをBOOLに保存され、 しばらく(保存された!) { 試み { context.SaveChanges(); trueに保存された=; } キャッチ(DbUpdateConcurrencyException EX) { VAR ex.Entries.Single S =(); s.Reload(); //リフレッシュデータ更新が成功するまで } }
コードのリロード方法のセクションエンティティキャッシュの最新の値にデータベースの更新を照会することで、データベースの動作を見ることができます