SQL Server2005でのデッドロックの診断


82

Stack Overflow SQL Server 2005データベースで、いくつかの有害ではあるがまれなデッドロック状態が発生しています。

プロファイラーを添付し、デッドロックのトラブルシューティングに関するこの優れた記事を使用してトレースプロファイルを設定し、多数の例をキャプチャしました。奇妙なことに、デッドロック書き込みは常に同じです:

UPDATE [dbo].[Posts]
SET [AnswerCount] = @p1, [LastActivityDate] = @p2, [LastActivityUserId] = @p3
WHERE [Id] = @p0

他のデッドロックステートメントはさまざまですが、通常は、投稿テーブルを簡単に読み取るだけです。これは常にデッドロックで殺されます。これが例です

SELECT
[t0].[Id], [t0].[PostTypeId], [t0].[Score], [t0].[Views], [t0].[AnswerCount], 
[t0].[AcceptedAnswerId], [t0].[IsLocked], [t0].[IsLockedEdit], [t0].[ParentId], 
[t0].[CurrentRevisionId], [t0].[FirstRevisionId], [t0].[LockedReason],
[t0].[LastActivityDate], [t0].[LastActivityUserId]
FROM [dbo].[Posts] AS [t0]
WHERE [t0].[ParentId] = @p0

完全に明確にするために、書き込み/書き込みのデッドロックは発生していませんが、読み取り/書き込みが発生しています。

現在、LINQクエリとパラメータ化されたSQLクエリが混在しています。with (nolock)すべてのSQLクエリに追加しました。これはいくつかの助けになったかもしれません。また、昨日修正した1つの(非常に)不適切に記述されたバッジクエリがありました。これは、毎回実行するのに20秒以上かかり、その上で毎分実行されていました。これがいくつかのロックの問題の原因であることを望んでいました!

残念ながら、約2時間前に別のデッドロックエラーが発生しました。同じ正確な症状、同じ正確な犯人の書き込み。

本当に奇妙なことは、上記のロック書き込みSQLステートメントが非常に特定のコードパスの一部であるということです。それはだだけ新しい答えを質問に追加されたときに実行される-それは、新しい回答数と最後の日付/ユーザーと親の質問を更新します。これは、明らかに、私たちが行っている膨大な数の読み取りに比べてそれほど一般的ではありません!私の知る限り、アプリ内のどこにも大量の書き込みは行っていません。

NOLOCKは一種の巨大なハンマーだと思いますが、ここで実行するクエリのほとんどはそれほど正確である必要はありません。ユーザープロファイルが数秒古くなっていてもかまいませんか?

スコットハンゼルマンがここで説明しているように、LinqでNOLOCKを使用するのは少し難しいです

私たちは使用するという考えでいちゃつく

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

すべてのLINQクエリにこのセットが含まれるように、ベースデータベースコンテキストで。それがなければ、私たちが行うすべてのLINQ呼び出し(まあ、それらの大部分である単純な読み取り呼び出し)を3〜4行のトランザクションコードブロックでラップする必要があります。これは醜いです。

SQL 2005での些細な読み取りが書き込みでデッドロックする可能性があることに、少し不満を感じていると思います。書き込み/書き込みのデッドロックが大きな問題であることがわかりましたが、読み取りますか?ここでは銀行サイトを運営していません。毎回完璧な正確さを要求するわけではありません。

アイデア?考え?


すべての操作に対して新しいLINQto SQL DataContextオブジェクトをインスタンス化していますか、それともすべての呼び出しで同じ静的コンテキストを共有していますか?

ジェレミー、ほとんどの場合、ベースコントローラーで1つの静的データコンテキストを共有しています。

private DBContext _db;
/// <summary>
/// Gets the DataContext to be used by a Request's controllers.
/// </summary>
public DBContext DB
{
    get
    {
        if (_db == null)
        {
            _db = new DBContext() { SessionName = GetType().Name };
            //_db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
        }
        return _db;
    }
}

すべてのコントローラーに対して、またはページごとに、またはより頻繁に新しいコンテキストを作成することをお勧めしますか?


2
何<ahref = " en.wikipedia.org/wiki/... mode</a>あなたは、 "悲観的"(ロックベース)または"楽観的"(<HREFを使用している=」en.wikipedia.org/wiki/ …)?
ジョン・シラクサ

上記のGuyの回答に同意します。症状を回避しようとするのではなく、根本的な原因に対処してみませんか?AnswerCountの現在の合計を投稿テーブルに追加すると、潜在的なブロッキングリソースが作成されます。ジェフはStackOverflowのERDを投稿して、人々が批評できるようにしたいですか?
andyp 2008

2
うわー-スコットとのポッドキャストでこれについて聞いた。それがより良い設定で箱から出して出荷されないことも信じられません。これをDBAに紹介します(DBAも「nolock」を広範囲に使用しているため)
Dan Esparza

3
これがデッドロックであった理由については、samsaffron.com / archive / 2008/08/27 / Deadlocked +を参照してください。スナップショットアイソレーションをオンにすることは、この問題の良い解決策です。
サムサフラン

回答:


44

MSDNによると:

http://msdn.microsoft.com/en-us/library/ms191242.aspx

READ COMMITTEDSNAPSHOTまたはALLOWSNAPSHOT ISOLATIONデータベースオプションのいずれかがオンの場合、データベースで実行されたすべてのデータ変更に対して論理コピー(バージョン)が維持されます。特定のトランザクションによって行が変更されるたびに、データベースエンジンのインスタンスは、以前にコミットされた行のイメージのバージョンをtempdbに格納します。各バージョンには、変更を加えたトランザクションのトランザクションシーケンス番号が付けられています。変更された行のバージョンは、リンクリストを使用してチェーンされます。最新の行の値は常に現在のデータベースに保存され、tempdbに保存されているバージョン管理された行にチェーンされます。

短期間のトランザクションの場合、変更された行のバージョンは、tempdbデータベースのディスクファイルに書き込まれずにバッファプールにキャッシュされる場合があります。バージョン管理された行の必要性が短命である場合、それは単にバッファプールから削除され、必ずしもI / Oオーバーヘッドが発生するわけではありません。

余分なオーバーヘッドに対してわずかなパフォーマンスの低下があるように見えますが、無視できる場合があります。確認するためにテストする必要があります。

このオプションを設定して、本当に必要な場合を除いて、コードクエリからすべてのNOLOCKを削除してみてください。NOLOCKまたはデータベースコンテキストハンドラーでグローバルメソッドを使用してデータベーストランザクション分離レベルと戦うことは、問題に対するバンドエイドです。NOLOCKSは、データレイヤーの基本的な問題を覆い隠し、信頼性の低いデータの選択につながる可能性があります。この場合、行の自動選択/更新のバージョン管理が解決策のようです。

ALTER Database [StackOverflow.Beta] SET READ_COMMITTED_SNAPSHOT ON

3
「NOLOCKSはデータレイヤーの基本的な問題をマスクします」... NOLOCKはどのような問題をマスクしますか?NOLOCKが必要だと思う場合、どのような問題を探す必要がありますか?
マットハミルトン

3
この答えは「答え」になりますか?ミリ秒の読み取りがデッドロックする理由がまだわかりません-すぐに書き込みを強制終了しますか?「user13484」の答えは残念だと思いますが、その場合は言及されていません。
RichardTheKiwi 2011年

37

NOLOCKREADUNCOMMITTEDは、滑りやすい坂道です。デッドロックが最初に発生する理由を理解していない限り、これらを使用しないでください。「すべてのSQLクエリに(nolock)を追加しました」と言うのは心配です。追加する必要がNOLOCK WITHどこでもすることは、あなたのデータ層に問題を持っていることを確認しサインです。

更新ステートメント自体は少し問題があるように見えます。トランザクションの早い段階でカウントを決定しますか、それともオブジェクトからカウントしますか?AnswerCount = AnswerCount+1質問が追加されたときは、おそらくこれを処理するためのより良い方法です。そうすれば、正しいカウントを取得するためのトランザクションは必要なく、潜在的にさらされている同時実行の問題について心配する必要もありません。

多くの作業を行わず、ダーティ読み取りを有効にせずにこのタイプのデッドロックの問題を回避する簡単な方法の1つは、"Snapshot Isolation Mode"(SQL 2005の新機能)を使用することです。これにより、最後に変更されていないデータを常にクリーンに読み取ることができます。デッドロックされたステートメントを適切に処理したい場合は、それらをかなり簡単にキャッチして再試行することもできます。


4
私はJEzellと一緒です-私が最初に焦点を合わせたのは「SETAnswerCount = <固定値>」です。その価値はどこから来ているのですか?それは、トランザクションの他の場所で、たくさんのロックを取得する方法でそれを取得したのではないかと思います。それから始めます。そして、はい、グローバルNOLOCKはバンドエイドです。
コーワン

25

OPの質問は、なぜこの問題が発生したのかを尋ねることでした。この投稿は、他の人が解決できる可能性のある解決策を残しながら、それに答えることを望んでいます。

これはおそらくインデックス関連の問題です。たとえば、テーブルPostsに、ParentIDと更新されるフィールドの1つ(または複数)(AnswerCount、LastActivityDate、LastActivityUserId)を含む非クラスター化インデックスXがあるとします。

SELECTコマンドがインデックスXで共有読み取りロックを実行してParentIdで検索し、次にUPDATEコマンドが書き込み専用を実行している間に、クラスター化インデックスで共有読み取りロックを実行して残りの列を取得する必要がある場合、デッドロックが発生します。クラスター化インデックスをロックし、インデックスXを更新するには書き込み専用ロックを取得する必要があります。

これで、AがXをロックしてYを取得しようとしているのに対し、BがYをロックしてXを取得しようとしている状況が発生しました。

もちろん、これが実際に原因であるかどうかを確認するために、どのインデックスが機能しているかに関する詳細情報で彼の投稿を更新するOPが必要になります。


私はこの分析に同意します-SELECTとUPDATEは異なる順序で行を処理しているため、それぞれが他方が持っている行ロックを取得しようとしています。
マイクディミック

これは、このスレッド全体に対する最良の応答であり、デッドロックが実際に発生する理由についての唯一の説明になります。それがここで最高のものであるため、それは一番の答えではありません。
Jonathan Kehayias 2009

いくつかの答えは、2つのアトミックな単純なステートメントの間にあるロックについてのポイントを欠いています。これはそれを説明しようとする唯一の投稿です。ステートメントは単純ですが、テーブルの更新には複数のCIXおよびNCIXの更新が含まれる可能性があり、これは多くの操作に拡張されます。NCIXトラバーサル、CIXブックマークルックアップを含むREADについても同じです。これは、同じ順序でテーブルを結合することなどとは関係ありません(人々は質問を読みますか??)
RichardTheKiwi 2011年

18

私はこの質問とそれに付随する回答についてかなり不快です。「この魔法の粉を試してみてください!その魔法の粉はありません!」がたくさんあります。

取得されたロックを分析し、どのタイプのロックがデッドロックされているかを判断したことはどこにもわかりません。

あなたが示したのは、デッドロックではなく、いくつかのロックが発生することだけです。

SQL 2005では、以下を使用して、どのロックが解除されているかについての詳細情報を取得できます。

DBCC TRACEON (1222, -1)

デッドロックが発生したときに、より適切な診断ができるようにします。


13
デッドロックは、SQLServerのデッドロックモニターによって即座に処理されます。DMVは、デッドロックが発生していることに気付く前に犠牲者が選択されて殺されるため、デッドロックのトラブルシューティングには役立ちません。
Jonathan Kehayias 2009

14

すべての操作に対して新しいLINQto SQL DataContextオブジェクトをインスタンス化していますか、それともすべての呼び出しで同じ静的コンテキストを共有していますか?私はもともと後者のアプローチを試しましたが、覚えていることから、DBで不要なロックが発生しました。ここで、すべてのアトミック操作に対して新しいコンテキストを作成します。


10

家を焼き払ってNOLOCKでハエを捕まえる前に、プロファイラーでキャプチャする必要のあるデッドロックグラフを確認することをお勧めします。

デッドロックには(少なくとも)2つのロックが必要であることを忘れないでください。接続1にはロックAがあり、ロックBが必要です。接続2の場合はその逆です。これは解決できない状況であり、誰かが指定する必要があります。

これまでに示したことは、単純なロックによって解決されます。これは、SQLServerが一日中喜んで実行します。

あなた(またはLINQ)は、そのUPDATEステートメントを含むトランザクションを開始し、事前に他の情報を選択していると思われます。ただし、デッドロックグラフをさかのぼって各スレッドが保持しているロックを見つけてから、プロファイラーをさかのぼってそれらのロックが付与される原因となったステートメントを見つける必要があります。

このパズルを完了するには、少なくとも4つのステートメントがあると思います(または、複数のロックを取得するステートメント-おそらくPostsテーブルにトリガーがありますか?)。


7

ユーザープロファイルが数秒古くなっていてもかまいませんか?

いいえ、それは完全に受け入れられます。基本トランザクション分離レベルを設定することは、おそらく最善/最もクリーンな方法です。


5

一般的な読み取り/書き込みデッドロックは、インデックス順序アクセスに起因します。読み取り(T1)は、インデックスAで行を検索し、インデックスB(通常はクラスター化されている)で投影された列を検索します。書き込み(T2)はインデックスB(クラスター)を変更し、インデックスAを更新する必要があります。T1はAにS-Lckがあり、BにS-Lckが必要で、T2はBにX-Lckがあり、AにU-Lckが必要です。デッドロック、パフ。T1が殺されます。これは、OLTPトラフィックが多く、インデックスが少し多すぎる環境でよく見られます:)。解決策は、読み取りがAからBにジャンプする必要がない(つまり、Aに含まれる列、または投影リストから列を削除する)か、T2がBからAにジャンプする必要がない(インデックス付き列を更新しない)ようにすることです。残念ながら、linqはここではあなたの友達ではありません...


ところで、AとBは同じテーブルのインデックスです
Remus Rusanu 2009年

3

@ Jeff-私は間違いなくこれの専門家ではありませんが、ほぼすべての呼び出しで新しいコンテキストをインスタンス化することで良い結果が得られました。これは、ADOを使用するたびに新しいConnectionオブジェクトを作成するのと似ていると思います。とにかく接続プールが引き続き使用されるため、オーバーヘッドは思ったほど悪くはありません。

私はこのようなグローバル静的ヘルパーを使用しています:

public static class AppData
{
    /// <summary>
    /// Gets a new database context
    /// </summary>
    public static CoreDataContext DB
    {
        get
        {
            var dataContext = new CoreDataContext
            {
                DeferredLoadingEnabled = true
            };
            return dataContext;
        }
    }
}

そして、私はこのようなことをします:

var db = AppData.DB;

var results = from p in db.Posts where p.ID = id select p;

そして、私はアップデートについても同じことをします。とにかく、私はあなたほど多くのトラフィックを持っていませんが、ほんの一握りのユーザーで早い段階で共有DataContextを使用したとき、私は確かにいくつかのロックを取得していました。保証はありませんが、試してみる価値があるかもしれません。

更新:ここでも、コードを見ると、その特定のコントローラーインスタンスの存続期間中のみデータコンテキストを共有しています。これは、コントローラー内の複数の呼び出しによって同時に使用されない限り、基本的には問題ないようです。このトピックに関するスレッドで、ScottGuは次のように述べています。

コントローラは単一のリクエストに対してのみ存続します-したがって、リクエストの処理の最後に、コントローラはガベージコレクションされます(つまり、DataContextが収集されます)。

とにかく、それはそうではないかもしれませんが、おそらくいくつかの負荷テストと組み合わせて、おそらく試してみる価値があります。


3

Q.なぜ保管しているのですか AnswerCount中でPosts最初の場所でのテーブル?

別のアプローチは、への「書き戻し」を排除することです。 Postsテーブルに保存せずに、AnswerCount必要に応じて投稿への回答数を動的に計算することによりテーブルです。

はい、これは追加のクエリを実行していることを意味します。

SELECT COUNT(*) FROM Answers WHERE post_id = @id

またはより一般的に(ホームページにこれを表示している場合):

SELECT p.post_id, 
     p.<additional post fields>,
     a.AnswerCount
FROM Posts p
    INNER JOIN AnswersCount_view a
    ON <join criteria>
WHERE <home page criteria>

しかし、これは通常INDEX SCAN、リソースの使用において、を使用するよりも効率的である可能性があります。READ ISOLATION

猫の皮を剥ぐ方法は複数あります。データベーススキーマの時期尚早な非正規化は、スケーラビリティの問題を引き起こす可能性があります。


3

READ_COMMITTED_SNAPSHOTをオンに設定する必要がありますが、デフォルトではオンに設定されていません。これにより、MVCCセマンティクスが得られます。これは、Oracleがデフォルトで使用するものと同じです。MVCCデータベースを持つことは非常に便利であり、データベースを使用しないことは非常識です。これにより、トランザクション内で以下を実行できます。

ユーザーの更新SetFirstName = 'foobar'; // 1年間寝ることを決定します。

その間、上記をコミットしなくても、誰もがそのテーブルから問題なく選択し続けることができます。MVCCに慣れていない場合は、MVCCなしで生活できたことにショックを受けるでしょう。真剣に。


3

デフォルトをコミットされていない状態で読み取るように設定することはお勧めできません。あなたは間違いなく矛盾をもたらし、あなたが現在持っているものよりも悪い問題に終わるでしょう。スナップショットアイソレーションはうまく機能するかもしれませんが、SQL Serverの動作方法が大幅に変更され、tempdbに大きな負荷がかかります。

実行する必要があることは次のとおりです。(T-SQLで)try-catchを使用して、デッドロック状態を検出します。発生した場合は、クエリを再実行してください。これは、標準的なデータベースプログラミングの方法です。

PaulNielsonのSqlServer 2005 Bibleには、この手法の良い例があります

これが私が使用する簡単なテンプレートです:

-- Deadlock retry template

declare @lastError int;
declare @numErrors int;

set @numErrors = 0;

LockTimeoutRetry:

begin try;

-- The query goes here

return; -- this is the normal end of the procedure

end try begin catch
    set @lastError=@@error
    if @lastError = 1222 or @lastError = 1205 -- Lock timeout or deadlock
    begin;
        if @numErrors >= 3 -- We hit the retry limit
        begin;
            raiserror('Could not get a lock after 3 attempts', 16, 1);
            return -100;
        end;

        -- Wait and then try the transaction again
        waitfor delay '00:00:00.25';
        set @numErrors = @numErrors + 1;
        goto LockTimeoutRetry;

    end;

    -- Some other error occurred
    declare @errorMessage nvarchar(4000), @errorSeverity int
    select    @errorMessage = error_message(),
            @errorSeverity = error_severity()

    raiserror(@errorMessage, @errorSeverity, 1)

    return -100
end catch;    

2
なぜこの解決策は私をうんざりさせるのですか?!! 私はなぜデッドロックがあるのか​​を見ているでしょう..問題に対する本当に貧しい人のバンドエイドではありません。
Pure.Krome 2008年

2

過去に私のために働いたことの1つは、すべてのクエリと更新が同じ順序でリソース(テーブル)にアクセスすることを確認することです。

つまり、あるクエリがTable1、Table2の順序で更新され、別のクエリがTable2、Table1の順序で更新されると、デッドロックが発生する可能性があります。

LINQを使用しているため、更新の順序を変更できるかどうかわからない。しかし、それは注目すべきことです。


1

ユーザープロファイルが数秒古くなっていてもかまいませんか?

数秒は間違いなく許容されます。とにかく、膨大な数の人が同時に回答を提出しない限り、それほど長くはないようです。


1

私はこれについてジェレミーに同意します。コントローラごとに、またはページごとに新しいデータコンテキストを作成する必要があるかどうかを尋ねます。私は、独立したクエリごとに新しいデータコンテキストを作成する傾向があります。

私は現在、あなたと同じように静的コンテキストを実装するためのソリューションを構築しています。ストレステスト中にサーバーの獣に大量のリクエスト(百万以上)を投げたとき、読み取り/書き込みロックもランダムに取得していました。

クエリごとにLINQレベルで異なるデータコンテキストを使用するように戦略を変更し、SQLサーバーが接続プールの魔法を実行できると信頼するとすぐに、ロックが消えたように見えました。

もちろん、私は時間のプレッシャーにさらされていたので、同時に多くのことを試みたので、それがそれを修正したものであると100%確信することはできませんが、私は高いレベルの自信を持っています-それをそのように言いましょう。


1

ダーティリードを実装する必要があります。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

クエリで完全なトランザクションの整合性を絶対に必要としない場合は、同時実行性の高いテーブルにアクセスするときにダーティリードを使用する必要があります。あなたの投稿テーブルはその1つだと思います。

これにより、いわゆる「ファントムリード」が発生する可能性があります。これは、クエリがコミットされていないトランザクションからのデータに作用する場合です。

ここでは銀行サイトを運営していません。毎回完璧な精度は必要ありません。

ダーティリードを使用します。彼らはあなたに完全な正確さを与えないという点であなたは正しいです、しかし彼らはあなたのデッドロックの問題を解決するはずです。

それがなければ、私たちが行うすべてのLINQ呼び出し(まあ、それらの大部分である単純な読み取り呼び出し)を3〜4行のトランザクションコードブロックでラップする必要がありますが、これは醜いです

「ベースデータベースコンテキスト」にダーティリードを実装する場合、トランザクションの整合性が必要な場合は、より高い分離レベルを使用して個々の呼び出しをいつでもラップできます。


1

では、再試行メカニズムの実装の問題は何ですか?デッドロックが発生する可能性は常にあるので、それを特定して再試行するロジックを用意してみませんか?

他のオプションの少なくともいくつかは、再試行システムがめったに起動しないときに常に取られるパフォーマンスペナルティを導入しませんか?

また、再試行が発生したときに何らかのログを記録することを忘れないでください。そうすれば、まれに頻繁に発生するような状況に陥ることがありません。


1

Jeremyの答えが表示されたので、ベストプラクティスは、データ操作ごとに新しいDataContextを使用することだと聞いたのを覚えていると思います。Rob Coneryは、DataContextに関するいくつかの投稿を書いています。彼は、シングルトンを使用するのではなく、常にそれらをニュースにしています。

Video.Showに使用したパターンは次のとおりです(CodePlexのソースビューへのリンク):

using System.Configuration;
namespace VideoShow.Data
{
  public class DataContextFactory
  {
    public static VideoShowDataContext DataContext()
    {
        return new VideoShowDataContext(ConfigurationManager.ConnectionStrings["VideoShowConnectionString"].ConnectionString);
    }
    public static VideoShowDataContext DataContext(string connectionString)
    {
        return new VideoShowDataContext(connectionString);
    }
  }
}

次に、サービスレベルで(または更新の場合はさらに詳細に):

private VideoShowDataContext dataContext = DataContextFactory.DataContext();

public VideoSearchResult GetVideos(int pageSize, int pageNumber, string sortType)
{
  var videos =
  from video in DataContext.Videos
  where video.StatusId == (int)VideoServices.VideoStatus.Complete
  orderby video.DatePublished descending
  select video;
  return GetSearchResult(videos, pageSize, pageNumber);
}

0

コミットされていない読み取りに分離レベルを設定しても他のクエリに悪影響がない限り、Gregに同意する必要があります。

ジェフ、データベースレベルで設定すると、次のようなクエリにどのように影響するかを知りたいと思います。

Begin Tran
Insert into Table (Columns) Values (Values)
Select Max(ID) From Table
Commit Tran

0

プロフィールが数分古くなっていても問題ありません。

失敗した後、読み取りを再試行していますか?大量のランダム読み取りを実行すると、読み取りできないときにヒットする可能性があります。私が使用しているアプリケーションのほとんどは、読み取りの数に比べて書き込みが非常に少なく、読み取りは取得している数に近いとは限りません。

「READUNCOMMITTED」を実装しても問題が解決しない場合は、処理について詳しく知らずに支援するのは困難です。この動作に役立つ他のチューニングオプションがあるかもしれません。MSSQLの第一人者が助けにならない限り、問題をベンダーに提出することをお勧めします。


0

私はすべてを調整し続けます。ディスクサブシステムはどのように機能していますか?ディスクキューの平均の長さはどれくらいですか?I / Oがバックアップしている場合、本当の問題はデッドロックしているこれら2つのクエリではなく、システムをボトルネックにしている別のクエリである可能性があります。調整された20秒かかるクエリについて言及しましたが、他にありますか?

実行時間の長いクエリの短縮に焦点を当てれば、デッドロックの問題はなくなるでしょう。


0

同じ問題があり、サーバーでDTSが有効になっていないため(!)、TransactionScopeで「IsolationLevel = IsolationLevel.ReadUncommitted」を使用できません。

それは私が拡張メソッドでしたことです:

public static void SetNoLock(this MyDataContext myDS)
{
    myDS.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
}

したがって、重要な同時実行テーブルを使用する選択者に対して、次のような「nolock」を有効にします。

using (MyDataContext myDS = new MyDataContext())
{
   myDS.SetNoLock();

   //  var query = from ...my dirty querys here...
}

推測は大歓迎です!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.