質問

誰かが使用の影響を説明できますか with (nolock) クエリで、いつ使用する必要があるか?

たとえば、トランザクション レートが高く、特定のテーブルに大量のデータが含まれる銀行アプリケーションがある場合、どの種類のクエリで nolock が問題ありませんか?常に使用する必要がある/絶対に使用しない方がよい場合はありますか?

役に立ちましたか?

解決

(NOLOCK)WITHは、トランザクション分離レベルとしてREAD UNCOMMITEDを使用するのと同じです。だから、あなたはその後、ロールバックされ、コミットされていない行を読み取るリスク、データベースにそれを作ったことがない、すなわちデータを立ちます。それは他の操作によりデッドロックされて読み取りを防止することができながら、だから、それはリスクが付属しています。高いトランザクション・レートと銀行業務アプリケーションでは、おそらくあなたが私見それを解決しようとしているものは何でも問題への適切なソリューションであることを行っていない。

他のヒント

問題は、何が悪いことなのかということです。

  • デッドロック、または
  • 間違った値ですか?

金融データベースの場合、デッドロックは間違った値よりもはるかに悪いです。逆に聞こえるかもしれませんが、聞いてください。DB トランザクションの従来の例では、2 つの行を更新し、一方から減算し、もう一方に加算します。それは間違いです。

金融データベースではビジネス トランザクションを使用します。つまり、各アカウントに 1 行を追加します。これらのトランザクションが完了し、行が正常に書き込まれることが最も重要です。

一時的に口座残高を間違えることは大したことではありません。それが一日の終わりの調整の目的です。また、データベースからのコミットされていない読み取りよりも、2 台の ATM が同時に使用されているため、口座からの当座貸越が発生する可能性がはるかに高くなります。

とはいえ、SQL Server 2005 では、発生したバグのほとんどが修正されました。 NOLOCK 必要。したがって、SQL Server 2000 以前を使用している場合を除き、これは必要ありません。

参考文献
行レベルのバージョニング

NOLOCKヒントの合法的な使用のためのテキストブックの例では、高い更新OLTPデータベースに対してレポートのサンプリングである。

局所例を取ります。大規模な米国のハイストリートの銀行が銀行の都市レベルの実行の最初の兆候を探して時間単位のレポートを実行したい場合は、NOLOCKクエリは都市ごとの現金預金と現金の引き出しを合計トランザクションテーブルをスキャンすることができます。そのようなレポートのためにロールバック更新トランザクションによる誤差の小さな割合は、報告書の値を小さくしないでしょう。

未使用すると、データベース・トランザクションで金融取引をラップしていない理由を確認してください(あなたが別の口座から資金を転送するときのように - あなたはで-時間トランザクションの片側をコミットしていない - 明示的なトランザクションが存在する理由です) 。それがあるようにそれは音としてあなたのコードは、ビジネストランザクションに脳死であっても、すべてのトランザクションデータベースがエラーや障害が発生した場合に暗黙のロールバックを行う可能性を秘めています。私は、この議論は、あなたの頭の上の方法だと思います。

あなたがロックの問題がある場合は、

は、バージョン管理を実装し、コードをクリーンアップ。

いいえロックだけではなく、それはファントムレコードと重複を返し、間違った値を返しません。

それは常に、クエリを高速に実行可能という一般的な誤解です。テーブル上にwriteロックがない場合、それはどんな違いがありません。ロックがテーブルの上にある場合、それは、クエリを高速化するかもしれませんが、ロックが最初の場所で発明された理由があります。

公平では、ここでNOLOCKヒントユーティリティを提供することができる二つの特別なシナリオがある

1)これが唯一の方法かもしれライブOLTPデータベースに対して長いクエリを実行する必要が事前-2005のSQL Serverデータベース

レコードとリターンが無期限にブロックされるUIと読者に制御をロックする

2)不十分な申請書。アプリケーションは、プリ2005またはバージョン管理のいずれかをオンにすることはできませんされ(第三者など)とデータベースを固定することができない場合NOLOCKはここに参考にすることができます。

NOLOCKREAD UNCOMMITTEDに相当し、しかしMicrosoftはUPDATEDELETE文のためにそれを使用してはならないと言います:

  

UPDATEまたはDELETEステートメントの場合:この機能は、Microsoft SQL Serverの将来のバージョンで削除されます。新しい開発作業ではこの機能を使用して避け、現在この機能を使用するアプリケーションを変更することを計画しています。

http://msdn.microsoft.com/en-us/library/ ms187373.aspxする

この記事では、SQL Server 2005に適用されますので、あなたはそのバージョンを使用している場合NOLOCKのサポートが存在します。将来もあなたのコード(あなたは汚い読み込みを使用することを決めたと仮定した場合)にするために、あなたのストアドプロシージャでこれを使用することができます:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

あなたはデータのみを読んでいるとき、あなたはそれを使用することができ、あなたは本当にあなたがまだコミットされていないデータを取り戻すかもしれないかどうかを気にしないでください。

これは、より高速な読み出し動作になることができますが、私は実際にどのくらいで言うことができない。

一般的に、私はそれを使用しないことをお勧めします - コミットされていないデータの読み取りがせいぜい少し混乱することができます。

それは通常、大丈夫です別のケースでは、データは、おそらくすでに熟成さだけ発生しない書き込みレポートデータベースです。この場合、しかし、このオプションはデフォルトの分離レベルを変更することにより、管理者はデータベースまたはテーブルレベルで設定されなければならない。

一般的なケースでは:あなたは、それは古いデータを読み取るために大丈夫だとの非常にの確信しているとき、あなたはそれを使用することができます。覚えておくべき重要なことは、その間違ったのを取得することにそのの非常に簡単です。例えば、それはあなたがクエリを書くときに大丈夫だとしても、あなたは必ずこれらのアップデートがより重要にするために、将来的にデータベースに変更されません何かありますか?

Iよまた、第二、それはおそらくだという考えのないのバンキングアプリで良いアイデア。または在庫アプリ。それともどこでもあなたが取引を考えている。

簡単な答えは - あなたのSQLがデータを変更されていない時はいつでも、あなたは(ロックを経由して)他の活性を妨害する可能性があるクエリがある

これは、クエリは、たとえば、1秒以上かかる場合は特に、レポートのために使用されるすべてのクエリに対して検討する価値があります。

あなたはOLTPデータベースに対して実行しているOLAPタイプのレポートを持っている場合は、

これは特に便利です。

尋ねる最初の質問は、しかし、「なぜ私はこれを心配するのですか?」です誰かが「何をしてみてください」モードであり、これは予想外の結果はそうではありません一つのケースであるとき、私の経験lnを、デフォルトのロック動作をfudgingすることはしばしば行われます。あまりにも頻繁に、それは時期尚早な最適化の場合だと、あまりにも簡単にアプリケーションに組み込まれたままに得ることができます「念のため」。それが解決し何の問題、あなたはそれをやっている理由を理解することが重要だ、とあなたは、実際に問題を抱えているかどうか。

私の2セントを - それはあなたがレポートを生成する必要がある場合)WITH (NOLOCKを使用する意味があります。この時点で、データがあまり変化しない&あなたがそれらのレコードをロックしたいとは思わないでしょう。

あなたが金融取引を処理している場合は、

あなたはnolockを使用することはありません。 nolockは最高の多くのアップデートを持っているとあなたが得るレコードはおそらく古くなることができれば、あなたが気にしない大きなテーブルから選択するために使用されます。

あなたが潜在的に背中に書かれており、正しいデータを取得できませんされていたレコードからデータを読み取ることができてます。

財務記録(ほとんどのアプリケーションでは、ほとんどすべての他のレコード)についてはnolockは大混乱をもたらすだろう

私がやるべき事のための「次のバッチ」を取得するために使用しました。それは、この場合であって、正確な項目を重要ではありませんし、私はこの同じクエリを実行しているユーザーの多くを持っています。

短い答え:

絶対に使用しないでください WITH (NOLOCK).

長い答え:

NOLOCK はデータベースの読み取りを高速化する魔法の方法としてよく利用されますが、私は可能な限り使用を避けるようにしています。

結果セットには、まだコミットされていない行が含まれている可能性があり、多くの場合、後でロールバックされます。

エラーまたは結果セットは空であるか、行が欠落しているか、同じ行が複数回表示される場合があります。

これは、データの読み取りと同時に他のトランザクションがデータを移動しているためです。

READ COMMITTED では、複数のユーザーが同じセルを同時に変更すると、単一列内のデータが破損するという問題が追加されます。

他にも副作用があり、最初に得られると期待していた速度の向上が犠牲になります。

逃げられる場所で使えばいいじゃないかという議論もあるかもしれないが、一体どうなのだろうか。破損したデータが許容される状況は思いつきません。

NOLOCK は決して使用しないでください。

(これまで)

あなたが「汚い」データで大丈夫です。

使用NOLOCK。これNOLOCKはまた、修飾されたプロセスおよび/またはコミットされていないデータであるデータを読み出すことができることを意味します。

これは、高トランザクション環境でそれを使用するために、一般的には良い考えではありません、それは、クエリのデフォルトのオプションではありません理由です。

私は、特にSQLServerの中で(NOLOCK)ヒントを使用して高い活性を持つ2000のデータベースを使用します。私はそれは、SQL Serverが2005年に必要とされていることは間違いないです。彼はSPIDのレコードロックの多くを気づいたので、私は最近、クライアントのDBAの要求に応じてSQL Server 2000でそのヒントを追加しました。

私が言えることは、ヒントを使用して私たちを傷つけるとロックの問題は、自分自身を解決するためなされたように見えるしていないということです。その特定のクライアントのDBAは、基本的には、私たちがヒントを使用することを主張します。

ちなみに、私が扱うデータベースは、企業、医療の請求システムへのバックエンドしているので、我々は参加し、多くのレコードと20+のテーブルの何百万人について話しています。私は通常のテーブルごとに、WITH(NOLOCK)ヒントを追加します(それはあなたがその特定のヒントを使用することはできません、その場合、派生テーブルは、でない限り)参加

最も簡単な答えは簡単な質問です - あなたは繰り返しであるためにあなたの結果が必要なのでしょうか?はい、その後NOLOCKSがどのような状況の下で適切でない場合は、

あなたは再現性を必要としない場合は、

そしてnolocksを使用すると、ターゲット・データベースに接続するすべてのプロセスを制御することはできません場合は特に、有用である可能性がある。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top