を開き、 EF4 で動作するTransactionScope
async のロードを実行してから、結果をコミットすることは可能ですか?Task
ObjectContext
現在のトランザクション スコープは EF4 でどのように推測されますか? タスクがトランザクションスコープとは異なるスレッドでスケジュールされた場合、これは失敗しますか?
を開き、 EF4 で動作するTransactionScope
async のロードを実行してから、結果をコミットすることは可能ですか?Task
ObjectContext
現在のトランザクション スコープは EF4 でどのように推測されますか? タスクがトランザクションスコープとは異なるスレッドでスケジュールされた場合、これは失敗しますか?
はい、そうです。手始めに、Entity Framework は、実行中のスレッドから「周囲の」トランザクション コンテキストを取得する (既定では System.Data.SqlClient) の下にあるプロバイダーを使用するだけです。したがって、そこから、唯一のトリックは、単一のトランザクションをTasks
スピンアップに伝播することです。この投稿で、これを行う方法を説明しました。
その投稿は、PLINQ によって生成されたタスクへの伝達に関するものでしたが、独自のTasks
. コードサンプルが必要な場合は、スポーンがどのように機能するかの基本的な詳細を教えてくださいTask
。良いサンプルコードを提供できます。
いいえ、(便利なことに) これを行うことはできません。
Drew Marsh の答えは正しいですが (トランザクションがスレッドの境界を越える手段が存在するということです)、それはあなたの役に立ちません。 ObjectContext
はスレッド セーフではありません。他のスレッドからアクセスしてはいけません。また、他のスレッドで更新するべきではありません。未定義の動作が発生します。おそらくデータの破損に遭遇し、(運が良ければ) クラッシュを引き起こします。
マルチスレッドObjectContext
アクセスが必要な場合は、たとえばロックを使用してアクセスを手動でシリアル化する必要があります。しかし、それを行うと、1 つのスレッドからコンテキストにアクセスするだけで済みます。通常はよりシンプルで、ほとんどの場合より高速です。トランザクションに問題はありません。
ObjectContext
スレッドを使用するのではなく、アクセスを手動で同期することを主張する場合はCommittableTransaction
、アンビエント トランザクションを使用するのではなく、プレーンを使用してそれを明示的に渡すこともできます。とにかくトランザクションを手動で制御する必要があるため、トリッキーな状態遷移 (どのスレッドが実行されているかの正確な詳細が重要であるがコードで明示的ではない) よりも、オブジェクトの明示的なハンドルを使用して制御する方が明確です)。
ところで、アンビエント トランザクションを使用する場合、特に C# 5 の非同期機能を使用する場合は、タスク スケジューリングに注意する必要があります。実行によってスレッドがいつ変更されるかを明確に認識する必要があるからです (私はこれを試したことはありませんが、残念ながら、私はあなたに何の指針も与えることができません)。
要約: これを行わないでください: (実際には DB の) 制限により、マルチスレッド化によって同時実行性が得られないObjectContext
ため、1 つのトランザクションを 1 つのスレッドに残してシンプルに保つこともできます。将来のメンテナーは、明確にしてくれてありがとう。