分離レベルが「コミット済み」と読み取られた場合、トランザクションログによって「コミット済み」になった結果のみが返されます。したがって、その時点で分離レベル「コミット済み」のクエリを開始すると、SQLトランザクションログには、そのログにコミット済みとして投稿されたトランザクションのみが表示されます。選択の途中で誰かがレコードを投稿した場合、その時点で、操作が終了するまで「コミットされていない」と見なされ、「コミットされた」と見なされます。ただし、レベルを「コミットされていない」に変更しても、データは途中で取得されないはずです。トランザクションログに従って、操作を開始した時点でエンジンが利用できるものを取得する必要があります。
コミット済みと非コミット済みは、選択時に、選択に基づいて存在するレコードをシステムに取得します。つまり、3,000,000レコードと200,000レコードを挿入すると言ったとしても、一度に1つずつコミットしていて、コミットしたのは100,000のみで、ログの操作を認識しているのは100,000でしたが、まだコミットしていません。
コミットされた場合は3,100,000になり、コミットされていない場合は3,200,000になります。しかし、いくつかの考え方があり、昨日誰かとこれについて話し合ったところです。コミットされていない場合は、コミットされていない結果が得られ、まだ設定されていないログを読んでいるという点で「ダーティリード」と呼ばれます(反逆者)。あなたは「データベースねえ、あなたが何を受け取ったのかは気にしない、それが完成したのは今すぐ欲しい」と言っています。あなたがコミットしたと言うとき、あなたは次のように言っています:「データベース私は修飾されたデータだけが欲しい、何かが完成していなければ私はそれを望まない」。
それぞれの利点:
コミットされていない場合、何もロックされません。あなたは基本的にシステムにこう言っています。「何もロックアウトしないでください。システムを自由に通過させて、そこにあるものを取得します。何かを変更してもかまいません。操作の瞬間にそれが欲しいのです。」これを実行するときに何かが挿入または更新しようとしている場合、それはロックされません。
Committedは、操作が完了するまでコミットするために処理中のものを除いて、何もロックしません。返されたデータが確定されていることを確認しても安全ですが、トランザクションをブロックして挿入または投稿しようとするリスクがあります。あなたは基本的にデータベースに次のように言っています。「アクセスしているテーブルでコミットを続行する前に、終了するのを待ってください。データが正確である必要があるので、完了するまで渡してください」。これにより、収集元のテーブルで読み取りを実行しているときにデータがロックされる可能性があります。ほとんどの選択はほぼ瞬時であるため、これはそれほど一般的ではありませんが、1秒間に数千のレコードを投稿することに基づいてトランザクションを行う巨大なシステムでは、大きな懸念事項です。
正直なところ、私の議論では、私はコミットされていないことを好み、他の人はコミットされていることを好みました。プロダクションインサートを停止するよりも、ダーティデータを取得する方がはるかに許容できると私は主張しました。彼らは、ファントムリードや他のインスタンスはもっと悪いと主張しました。これは意見であり、SQLシステムは挿入と選択を中心に設計されていますが、他のシステムから少し離れることなく、両方を非常に高速に実行できることはめったにありません。正確なレポートが必要な場合の私の答えは、夜間のバックアップ、SSISパッケージ、バイナリコレクション、またはスナップショットやコミットなどの分離レベルで同様の処理を行い、そのデータをどこかに配置することです。データがファイナライズされ、後で変更されないようにロックされていることがわかっている方法でデータが設定されていることを確認して、そのデータを報告します。本番データをホットに報告しないでください。そうするように全員に指示するようにしてください。
あなたがデータベースを使用しているのが5人か10人しかない小さなお母さんとポップストアなら、おそらくそうではないでしょう。あなたが少し大きく、同じデータベースに50人がアクセスしている場合、それは害になりますが、日中にトリクルのデータを取得するという点で、約100ギガとセミトランザクションです。それでもおそらくそうではありません。200人のユーザーと複数のサーバーとデータベース、およびすべてのデータの複合を保存する主要なトランザクションデータベースの頭脳がある場合、それは害になりますか。絶対に、データを保存することが主な目的である場合は、集中的な操作を行うメインの本番データベースから読み取らないでください。
実世界の例からさらに指摘するために編集します。
そのため、通常、テーブル変数を使用していないほとんどの操作の先頭で(@Tableテーブルを宣言)、「トランザクション分離レベルの読み取りをコミットしないように設定」を設定します。クエリを実行するたびにこれを集中的に使用しますか?笑、私はそうしないことを望みます。実際、完全な開示は、膨大なトランザクションレポートのためにデータを一時テーブルで多く分離しているため、この時点からは決して役に立たない可能性があります。しかし、私は他の人に怒鳴られることはありません。私は彼らの挿入をブロックする長時間のトランザクションを持っています。また、多くの人がこれを行っていることもわかります。 "select * from table(nolock)" Iクエリにnolockヒントが埋め込まれているため、通常、このようなコードをあまりクエリの設計者に提供しません。私がみんなにこれをするように言うなら、彼らはそれを方針にするでしょう。
あなたはこれをする必要はありません、そして実際、何人かの人々は多分私について来て、これが間違っていると主張して彼らの側を投稿するでしょう。私はほとんどの場合、本番環境の保護のために行っています。間違っていると言った人は、最初にデータを取得したりリアルタイムで更新したりするのではなく、本番環境でテーブルをロックしてレポートするのが好きな理由を聞きたいと思います。マネージャーのところに行って、「200万件のレコードを投稿するのを待っていた巨大なアカウントと、それが実行されたインスタンスを知っていることを知っています。ジョン・ラングドンは、このクエリを実行したかったのです。ずさんな設計だったので、実行時間。彼はコミットを使用することを選択し、挿入を行っているテーブルのいくつかをヒットしているため、時折ロックが発生します。ビジネスよりもレポートを取得することが重要だと思います。」