TransactionScope
を開いて、EF4 ObjectContext
で動作するasync Task
の負荷を実行し、結果をコミットできますか?EF4、TransactionScopeおよびTask <>
現在のトランザクションスコープはEF4でどのように推測されますか?タスクがトランザクションスコープとは別のスレッドでスケジュールされている場合、これは失敗しますか?
TransactionScope
を開いて、EF4 ObjectContext
で動作するasync Task
の負荷を実行し、結果をコミットできますか?EF4、TransactionScopeおよびTask <>
現在のトランザクションスコープはEF4でどのように推測されますか?タスクがトランザクションスコープとは別のスレッドでスケジュールされている場合、これは失敗しますか?
はい、そうです。まず、Entity Frameworkは、実行中のスレッドから「アンビエント」トランザクションコンテキストを取得する(デフォルトではSystem.Data.SqlClient)下のプロバイダを使用します。だから、そこから、唯一のトリックはあなたがスピンアップTasks
に単一のトランザクションを伝播しています。 this postでここでそれをどうやって行うことができるか説明しました。
この投稿は、PLINQの産んだタスクに代わるものではありましたが、手作業で自分自身を回転させているのであれば、同じアプローチが可能です。Tasks
コードサンプルをご希望の場合は、Task
の産卵がどのように機能するかについての基本的な詳細を教えてください。私は良いサンプルコードを与えることができます。
いいえ、あなたはこれを(有益に)行うことはできません。
ドリュー・マーシュの回答は正しいですが(トランザクションをスレッド間の境界にする手段がある)、それはあなたを助けません。 ObjectContext
はスレッドセーフではありません - 他のスレッドからアクセスしないでください。間違いなくは他のスレッドで更新しないでください。あなたは未定義の振る舞いをします:データ破損に遭遇するでしょう。運が良ければクラッシュを引き起こします。
マルチスレッドObjectContext
にアクセスする場合は、ロックを使用してアクセスを手動でシリアル化する必要があります。しかし、それを行うならば、あなたは単に一つのスレッドから文脈にアクセスするだけかもしれません。通常はより簡単でほとんど常に高速です。それでは、トランザクションに問題はありません。
スレッドを使用するのではなくObjectContext
へのアクセスを手動で同期しようとしている場合は、平文CommittableTransaction
を使用して、周囲トランザクションを使用するのではなく明示的に渡すこともできます。トランザクションを手動で制御する必要があるため、トリッキーな状態遷移ではなく、オブジェクトの明示的なハンドルを使用して明示的に処理する必要があります(コード内で重要ではないスレッドの正確な詳細が実行されます)。
ところで、アンビエントトランザクションを使用している場合、特にC#5の非同期機能を使用したタスクスケジューリングに注意してください。実行によってスレッドが変更されるタイミングを明確に把握する必要があります残念ながらこれを試したことはないので、私はあなたに何か指針を与えることはできません)。
概要:ちょうどこれをしない:あなたはが原因ObjectContext
(および実際には、DB)の限界にマルチスレッドによる同時実行をを獲得していないので、あなたにも1つのスレッドに1つのトランザクションを残しておくかもしれませんそれは簡単です。将来のメンテナーは明快さに感謝します。