3

こんにちは、Entity Framework 4.1 コードの最初のアプローチを使用しています。MyContainerを継承するクラスがありDBContextます。

各ステップが多くのリポジトリ メソッド (約 60) にアクセスする 7 つのステップを持つプロセスがあります。このプロセスは、ビジネス ロジックとユーザーの要件に応じて、自動または手動で実行されます。自動プロセスのパフォーマンスの観点から、コンテキスト、つまりMyContainer一度のオブジェクトを作成し、それをすべてのメソッドに渡し、プロセスの最後に破棄して正常に動作し、パフォーマンスを向上させました.しかし、このプロセスが手動で実行されると、同じメソッドが実行されますコンテナはメソッド自体で作成および破棄されます。以下に例を示しますが、これは大まかなコードです。

public bool UpdateProcess(Process process, MyContainer container = null)
    {
        bool disposeContainer = false;
        if (container == null)
        {
            container = new MyContainer();
            disposeContainer = true;
        }
        var result = SaveProcess(container, process);
        container.SaveChanges();
        if (disposeContainer)
            container.Dispose();
        return result;
    }

自動プロセスの場合、トランザクションはプロセスの開始時に作成され、プロセスの終了時に終了します。手動トランザクションの場合、ui のユーザー アクションに従って呼び出されるメソッドの bll で作成されます。自動プロセスが実行されているとします。同時に、ユーザーが ui で何らかのアクションを実行しました"Transaction (Process ID 65)「別のプロセスでリソースをロックするときに例外がデッドロックされ、選択されました」というメッセージが表示されます UpdateProcess() メソッドが手動プロセスと自動プロセスの両方から一緒に呼び出されると、container.SaveChanges() でそれを取得します.

どんな助けでも大歓迎です。

このリポジトリメソッドでトランザクションスコープを作成すると

public bool UpdateProcess(Process process, MyContainer container = null)
 {         bool disposeContainer = false;        
           if (container == null)  
           {             
                  container = new MyContainer();         
                  disposeContainer = true;         
            }
       using(var trans=new TransactionScop(TransactionScopeOption.RequiresNew))        
       { 
          var result = SaveProcess(container, process);
          container.SaveChanges();
          trans.Complete();
       }        
          if (disposeContainer)           
          container.Dispose();        
          return result;   
 } 

それは正常に動作します。ただし、トランザクションは既に bll で作成されているため、リポジトリにトランザクションを作成したくありません。

どんな助けでも感謝されます。

4

1 に答える 1

2

あなたが抱えている問題 (SQL デッドロック) は、ほとんどの重要なクライアント (データベース システム) に共通しており、解決が非常に難しい場合があります。

デッドロックが発生する可能性があるコードを設計する際の主な規則は、デッドロックが発生することを想定し、アプリケーションを適切に処理するように設計することです。これは通常、トランザクションを再送信することで処理されます。マイクロソフトがここで文書化しているように

デッドロックは最小限に抑えることができますが、完全に回避することはできません。そのため、デッドロックを処理するようにフロントエンド アプリケーションを設計する必要があります。

デッドロックを最小限に抑えるために、私が取っている通常のアプローチは次のとおりです。

  1. デッドロック グラフを有効にしてプロファイラーを実行し、すべてのデッドロックをキャプチャする
  2. すべてのデッドロックをテキストにエクスポートし、それらが発生している理由を調査します
  3. テーブル ヒントを使用したり、トランザクションの分離レベルを下げたりすることで、これらを最小限に抑えることができることを確認してください。
  4. 操作の順序を変更するなど、他の手段でそれらを最小化できるかどうかを確認します
  5. 最後に、これがすべて完了したら、データベースと通信してトランザクション/クエリなどを再送信するたびに、デッドロックをトラップしていることを確認してください。
于 2012-05-21T12:38:56.223 に答える