4

私はここや他の場所でしばらく探していましたが、NOLOCKを使用したLinq-TO-SQLが不可能な理由に対する適切な答えを見つけることができません。

with(NOLOCK)ヒントをLinq-To-SQLコンテキスト(1つのSQLステートメントに適用)に適用する方法を検索するたびに、IsolationLevelをReadUncommittedに設定してトランザクション(TransactionScope)を強制するように人々が答えることがよくあります。まあ-彼らはこれが接続がトランザクションを開く原因になるとはめったに言いません(私がどこかで読んだことは手動で閉じられていることを確認する必要があります)。

私のアプリケーションでReadUncommittedをそのまま使用するのは、実際にはそれほど良くありません。現在、相互に同じ接続に対してコンテキストステートメントを使用しています。好き:

using( var ctx1 = new Context()) {
    ... some code here ...
    using( var ctx2 = new Context()) {
        ... some code here ...
        using( var ctx3 = new Context()) {
            ... some code here ...
        }
        ... some code here ...
    }
    ... some code here ...
}

合計実行時間が1秒で、同時に多数のユーザーがいる場合、分離レベルを変更すると、接続プール内のすべての接続が使用されているため、コンテキストは相互に接続を解放するのを待機します。

したがって、(多くの理由で)「nolock」に変更する理由の1つは、デッドロックを回避することです(現在、1日に1つの顧客のデッドロックがあります)。上記の結果は単なる別の種類のデッドロックであり、実際には私の問題を解決しません。

だから私ができることは次のとおりです。

  1. 同じ接続のネストされた使用を避けてください
  2. サーバーで接続プールのサイズを増やします

しかし、私の問題は次のとおりです。

  1. これは、コードのリファクタリングの行が多いため、近い将来には不可能であり、アーキテクチャと競合します(これが良いか悪いかについてコメントし始めることさえありません)
  2. もちろんこれは機能しますが、これは私が「対症療法」と呼ぶものです。アプリケーションがどれだけ成長するか、そしてこれが将来の信頼できる解決策であるかどうかはわかりません(そして、最終的にはより多くのユーザーが影響を受けるというさらに悪い状況)

私の考えは次のとおりです。

  1. NoLockが(トランザクションを開始しないステートメントごとに)不可能であるというのは本当に本当ですか?
  2. 1が真の場合-本当に真である可能性があります。他の誰もこの問題を取得して、SQLへの一般的なlinq変更で解決しましたか?
  3. 2が真の場合-なぜこれは他の人にとって問題ではないのですか?
    1. 多分私が見たことがない別の回避策はありますか?
    2. 同じ接続(ネストされた)を何度も使用することは、誰もこの問題を抱えていないほど悪い習慣ですか?
4

1 に答える 1

2

NOLOCK1:LINQ-to-SQLでは、実際に;のようなヒントを示すことはできません。ただし、独自のTSQLを記述して、などを使用することは可能です。ExecuteQuery<T>

2:エレガントな方法で解決することは、率直に言って、かなり複雑になります。また、不適切に使用している可能性が高くなります。たとえば、「デッドロック」シナリオでは、最初の読み取りで書き込みロックUPDLOCKが確実に行われるようにするために、実際には(最初の読み取り中に)使用する必要があることを賭けます。これにより、2番目以降のクエリが読み取りロックを取得するのを防ぐため、通常、デッドロックではなくブロッキングが発生します

3:接続の使用は必ずしも大きな問題ではありません(ただし、通常は接続を共有しないことに注意してくださいnew Context() 接続を共有するには、使用しますnew Context(connection))。この問題が発生した場合、考えられる解決策は3つあります(「ヒントサポート付きのORMを使用する」を除外した場合)。

  • 明示的なトランザクション(接続レベルのトランザクションである必要はありませんTransactionScopeを使用して、分離レベルを指定します
  • ヒントを使用して独自のTSQLを作成する
  • 接続レベルの分離レベルを使用します(コメントとして追加した警告に注意してください)

IIRCには、データコンテキストとoverrideトランザクション作成コードの一部をサブクラス化して、内部で作成するトランザクションの分離レベルを制御する方法もあります。

于 2011-12-13T11:09:09.013 に答える