これは、データベース分離レベルに関するポピュラーサイエンスの記事です。データベースにおける有名なファントム リード現象を理解することを目的としています。トピックに焦点を当てるため、ダーティ リードと非反復リードについては説明しません。 トランザクション分離レベルMySQL には 4 つのトランザクション分離レベルがあります。
ファントムリーディングとは何ですか?ファントム リードに関する誤った理解: ファントム リードとは、トランザクション A が 2 つの選択操作を実行して異なるデータ セットを取得することを意味します。つまり、選択 1 では 10 個のレコードが取得され、選択 2 では 11 個のレコードが取得されます。これは実際にはファントム リードではなく、非反復読み取りの一種であり、RU RC レベルでのみ発生し、MySQL のデフォルトの RR 分離レベルでは発生しません。 ファントムリーディングについての私の理解は次のとおりです。 ファントム リードは、トランザクション内の複数の読み取りから取得された結果セットが異なることを意味するものではありません。ファントム リードに関してより重要なのは、特定の選択操作から取得された結果セットによって表されるデータ状態が、後続のビジネス操作をサポートできないことです。具体的には、選択したレコードが存在せず、このレコードを挿入しようとしているが、挿入を実行すると、このレコードがすでに存在し、挿入できないことがわかり、まるで錯覚のようだ。 例を挙げると理解しやすくなるかもしれません: mysql> テーブル user\G の作成を表示します ************************** 1. 行 **************************** テーブル: ユーザー テーブルの作成: CREATE TABLE `user` ( `id` int(11) NULLではない、 `name` varchar(32) デフォルト NULL, 主キー (`id`) ) エンジン=InnoDB デフォルト文字セット=utf8 2 つのトランザクション T1 と T2 をそれぞれ開始し、分離レベルを Reaptable-Read に設定します。 T1: mysql> グローバルトランザクション分離レベルを繰り返し読み取りに設定します。 mysql> 開始します。 mysql> ユーザーから * を選択します。 mysql> ユーザー値に挿入(1、 'jeff'); エラー 1062 (23000): キー 'PRIMARY' のエントリ '1' が重複しています mysql> ユーザーから * を選択します。 T2: mysql> グローバルトランザクション分離レベルを繰り返し読み取りに設定します。 mysql> 開始します。 mysql> ユーザー値に挿入(1、 'jeff'); mysql> コミット; T1 トランザクションは、テーブル内に ID 1 のレコードがあるかどうかを確認し、ない場合はそれを挿入します。 T2 は干渉レコードを挿入し、T1 でファントム リードが発生します。 上記の例では、トランザクション T2 を実行する前にトランザクション T1 が実行されるようにする必要があります。 上記の例では、T1 で読み取られたデータ状態が後続のアクションと意味的に矛盾しているため、T1 でファントム リードが発生します。クエリを実行すると、レコードが存在しないことが明確に示されますが、挿入を実行すると、主キーが重複していることが示されます。これはファントムの出現に似ているため、ファントム リードと呼ばれます。 ファントムリードを排除する方法MySQL には現在、ファントム リードを取り除く 2 つの方法があります。 1. 選択操作 (SELECT ... FOR UPDATE) に行 X ロックを手動で追加します。その理由は、InnoDB の行ロックがインデックスをロックするためです。現在のレコードが存在しない場合でも、現在のトランザクションはレコード ロックを取得します (レコードが存在する場合は行 X ロックが追加され、存在しない場合は次のキー ロック ギャップ X ロックが追加されます)。このようにして、他のトランザクションはこのインデックスのレコードを挿入できず、ファントム リードが排除されます。 mysql> 開始します。 mysql> id = 2 の場合、user から * を選択して更新します。 mysql> ユーザー値に挿入(2、 'tony'); mysql> コミット; T2: mysql> 開始します。 mysql> ユーザー値に挿入(2、 'jimmy'); エラー 1062 (23000): キー 'PRIMARY' のエントリ '2' が重複しています ここで、T1 が更新のためにクエリされると、インデックスは Innodb でロックされます (現在存在しない場合でも)。そのため、トランザクション T2 の挿入は、T1 がコミットされるまでブロックされます。このようにして、T1 は成功します。T1 の場合、ファントム リードは確かに排除されますが、T2 の挿入では重複した主キーが報告されますが、これも予想どおりです。 分離レベルを向上させてファントム リードを排除する別の方法については、興味のある方は自分で試してみてください。ここでは繰り返しません。システムが手動ロックを置き換える点を除けば、本質は同様です。 要約するRR は、MySQL トランザクションのデフォルトの分離レベルです。これは、トランザクションのセキュリティとパフォーマンスの間の妥協点です。ファントム リードについて正しく理解した後、開発者は必要に応じてファントム リードを防止するかどうかを決定できます。 SERIALIZABLE は悲観的であり、ファントム リードが常に発生すると想定しているため、トランザクションに必要なリソースに自動的かつ暗黙的に排他ロックを追加します。このリソースにアクセスする他のトランザクションはブロックされ、待機状態になります。トランザクションは安全ですが、パフォーマンスを慎重に考慮する必要があります。 InnoDB ロックはインデックス用なので注意が必要です。行レコードをロックします。存在する場合は、X ロックを追加します。そうでない場合は、次のキー ロック/ギャップ ロック/ギャップ ロックを追加します。これにより、InnoDB は、トランザクションによる特定のレコードの事前占有を実現できます。トランザクションが存在する限り、他のトランザクションはそれを占有できません。ロックについては後ほど特別記事で取り上げます。 以上がMySQLファントムリードとその解消方法の詳細な説明です。MySQLファントムリードとその解消方法の詳細については、123WORDPRESS.COMの他の関連記事をご覧ください。 以下もご興味があるかもしれません:
|
<<: HTMLハイパーリンクタグAのTARGET属性の詳細な説明
>>: Docker tomcatのメモリサイズを設定する方法
MySQL を長い間使用してきた多くの人は、これら 2 つのフィールド属性の概念をまだよく理解して...
目次1. ステートフック1. 基本的な使い方2. 更新3. 合併を実現する4. 遅延初期化状態5. ...
MySQL のロックロックは、並行環境におけるリソースの競合を解決する手段です。その中でも、楽観的並...
画像タグ <IMG> を挿入します。今日私たちが目にするカラフルなウェブページはすべて、...
ターミナル分割画面ツールは2つあります: screen と tmux 1. 画面分割を使用する(上下...
この記事は主にSQLシリアル番号取得コード例を紹介します。記事ではサンプルコードを詳細に紹介しており...
この記事の著者@子木yoyoが個人ブログに投稿したものです。 Web ページでもモバイル アプリでも...
1. イベントバブリング: JavaScript イベント伝播のプロセスでは、要素でイベントがトリガ...
目次成果を達成する利用可能なプラグインの紹介ニーズに応じてプラグインを選択するプラグインのインストー...
機能別に並べ替えNN: このタグをサポートする Netscape の以前のバージョンを示しますIE:...
1. ユーザーとパスワードの作成方法1. MySQLデータベースに入る mysql> mysq...
HTML画像にハイパーリンクを追加すると醜い青い枠線が表示される次のように:解決: CSS スタイル...
閉鎖による問題を回避するためのletについてオブジェクト指向の考え方を使用して、購入者情報の削除機能...
Canvas は HTML5 の新しいタグです。js を使用して Canvas 描画 API を操作...
目次序文: 1.DEFINERの簡単な紹介2. いくつかの注意点要約:序文: MySQL データベー...