web-dev-qa-db-ja.com

なぜNOLOCKはそのように実装されているのですか?

最近、SQL ServerでNOLOCKオプションを検索しました。私が発見したのは、テーブルでトランザクションがアクティブな場合、トランザクションがコミットまたはロールバックされるまで、SQL Serverは特定のテーブルからの読み取りさえ許可しないことです(私が理解した限り 「with(nolock)」 )を使用してください。

同時に、PostgreSQLなどの他のRDBMSでは、アクティブな書き込みトランザクションがある行から値を読み取ることができます。彼らはあなたに書く前にそこにあった価値をあなたに与えるだけです。特に、それはPostgreSQL MVCCでの動作のようです(私は 第13章同時実行制御の概要 から学びました)。

そして、私はこの燃える質問を持っています。 SQL Serverでデッドロックが発生する可能性があるのに、他のRDBMSで新しい値が書き込まれる前に古い値を取得するのはなぜですか?

注:正しく理解していない可能性があるので、質問します。

5

SQL ServerはデフォルトでRead Committed分離で動作します。

SQL Serverを他の実装のように動作させたい場合は、Read Committed Snapshot IsolationまたはSnapshot Isolationを探してください。

あなたはそれらについてもっと読むことができます ここ

完全な開示、私はブレントオザーアンリミテッドの従業員です

NOLOCKまたはRead Uncommittedの使用は、変更クエリの進行中にダーティリードやその他の意図しないアーティファクトを許可する可能性があるため、本番環境での本格的な使用には適していません。

10
Erik Darling

ブロッキングの問題を管理する方法を決定するには、最初に以下をお読みください。

SET TRANSACTION ISOLATION LEVEL(Transact-SQL) このMSDNの投稿を読むと、データとスループットの使用方法を管理する方法にいくつかの異なる構成があることがわかります。

非常にアクティブなサーバーでは、Read Committedスナップショット分離を使用しましたが、通常Read Committed分離は、ストレスの少ないシステムには十分です。

そして、あなたが行うすべての決定には副作用があります。

3
RLF

SQL標準では、分離レベルを同時トランザクションで認識できるもの(および読み取り現象の処理方法)として定義していますが、ベンダーは要件を満たす実装を自由に選択できます。
SQLServerは、歴史的にロックベースの同時実行制御の実装を使用し、他のRDMBSと比較してより積極的にリソースをロックします。ある程度は(READ_COMMITTED_SNAPSHOTオプションを有効にすることで)制御できますが、その名前が示すように、このオプションはREAD_COMMITTED分離レベルでのみ機能するため、他のRDBMS用に作成されたアプリケーションでも問題が発生する可能性があります。

2
a1ex07