1. はじめに 行ロックとテーブルロックの違いは面接で頻繁に出てくるはずです。MySQL のロックについて体系的に理解しておく必要があります。詳細については、自分で情報を調べる必要があります。この記事は、その答えを大まかにまとめたものです。 一般的な MySQL エンジンには MyISAM と InnoDB があり、InnoDB は MySQL のデフォルト エンジンです。 MyISAM は行ロックをサポートしていませんが、InnoDB は行ロックとテーブルロックをサポートしています。 他のデータベースと比較すると、MySQL のロック メカニズムは比較的単純です。最も注目すべき特徴は、異なるストレージ エンジンが異なるロック メカニズムをサポートしていることです。 MySQL は、大まかに次の 3 種類のロックにまとめることができます。
ロックするには? クエリ ステートメント (SELECT) を実行する前に、MyISAM は関連するすべてのテーブルに読み取りロックを自動的に追加します。更新操作 (UPDATE、DELETE、INSERT など) を実行する前に、関連するテーブルに書き込みロックを自動的に追加します。このプロセスではユーザーの介入は必要ないため、通常、ユーザーは LOCK TABLE コマンドを使用して MyISAM テーブルを直接明示的にロックする必要はありません。 明示的なロック: 共有ロック (読み取りロック) を書き込む方法は、共有モードでロックすることです。例: math>60 の zje から math を選択し、共有モードでロックします。 排他ロック (書き込みロック) は、更新の場合と同じように記述されます。例: 更新のために、math >60 となる zje から math を選択します。 2. テーブルロック デッドロックは発生せず、ロック競合の可能性が高く、同時実行性は低くなります。 MyISAM エンジン クエリ ステートメント (選択) を実行する前に、MyISAM は関係するすべてのテーブルに読み取りロックを自動的に追加し、追加、削除、および変更操作を実行する前に、関係するテーブルに書き込みロックを自動的に追加します。 MySQL テーブル レベルのロックには 2 つのモードがあります。
読み取りロックは書き込みをブロックし、書き込みロックは読み取りと書き込みの両方をブロックします。
MyISAM は、書き込みロック後は他のスレッドが操作を実行できなくなり、更新回数が多いとクエリがロックを取得するのが困難になり、永続的にブロックされるため、書き込みプライマリ テーブル エンジンとしては適していません。 3. 行ロック デッドロックは発生しますが、ロック競合の可能性は低く、同時実行性は高くなります。 MySQL の InnoDB エンジンは行ロックをサポートしています。Oracle とは異なり、MySQL の行ロックはインデックスを通じてロードされます。つまり、行ロックはインデックスに対応する行に追加されます。対応する SQL ステートメントがインデックスを使用しない場合、テーブル全体がスキャンされ、行ロックは実現できません。代わりに、テーブル ロックが使用されます。このとき、他のトランザクションは現在のテーブルに対して更新または挿入操作を行うことはできません。 テーブル `user` を作成します ( `name` VARCHAR(32) デフォルト NULL, `count` INT(11) デフォルト NULL, `id` INT(11) NOT NULL AUTO_INCREMENT, 主キー (`id`) ) エンジン=INNODB AUTO_INCREMENT=7 デフォルト文字セット=utf8 -- ここでは、主キーを id としてユーザーテーブルを作成します。 -- A は主キーを使用して挿入操作を実行しますが、トランザクションはコミットされません。update user set count=10 where id=1; -- B もこの時点で更新操作を実行します: update user set count=10 where id=2; -- 主キーによって選択されるため、行レベルのロックです。A と B は同じ行に対して操作しないため、B によって実行される操作は実行可能です。-- A は名前による挿入操作を実行しますが、トランザクションはコミットされません。update user set count=10 where name='xxx'; -- B もこの時点で更新操作を実行します: update user set count=10 where id=2; -- 非主キーまたはインデックスで選択されるため、テーブルレベルのロックにアップグレードされます。 -- B はテーブルを更新または挿入できません。A がトランザクションをコミットした場合にのみ、B は正常に実行できます。 更新用 select ステートメントの後に for update を追加すると、クエリされたデータに排他ロックが追加されます。他のトランザクションはそれを読み取ることはできますが、更新または挿入操作を実行することはできません。 -- ユーザー A は、id=1 のレコードをロックします。select * from user where id=1 for update; -- ユーザー B はこのレコードに対して操作を実行できません。update user set count=10 where id=1; -- ユーザーAがコミットした後、ユーザーBはレコードを操作できる 行ロックの実装には注意が必要です。
行ロックのシナリオ: ユーザー A が購入を行うと、サービス レイヤーはまずユーザーのアカウント残高を照会します。残高が十分であれば、その後の控除操作を実行します。この場合、照会中はレコードをロックする必要があります。 それ以外の場合、ユーザー B は、ユーザー A がアカウントを照会した後に購入する前に、ユーザー A のアカウントから資金を送金し、ユーザー A はユーザーの残高が十分かどうかをすでに判断しているため、残高が不足している可能性がありますが、引き落としは成功します。 この状況を回避するには、ユーザー A がレコードを操作するときに更新ロックを実行する必要があります。 拡張機能: ギャップロック 等価条件ではなく範囲条件を使用してデータを取得し、共有ロックまたは排他ロックを要求すると、InnoDB は条件を満たす既存のデータ レコードのインデックス項目をロックします。条件範囲内にキー値が存在しないレコードについては、ギャップと呼ばれます。 InnoDBはこの「ギャップ」もロックします。このロック機構はギャップロックと呼ばれます。 -- ユーザーA ユーザーを更新し、ID>2かつID<6の場合、count=8を設定します。 -- ユーザー B ユーザーを更新し、ID=5 の箇所で count=10 を設定します。 ユーザー A が上記の操作を実行した後にトランザクションをコミットしていない場合、B は 2 から 6 までのレコードを更新または挿入できず、ブロックされます。A がトランザクションをコミットすると、B の更新操作が実行されます。 提案:
これで、MySQL の行ロックとテーブルロックの意味と違いに関するこの記事は終了です。MySQL の行ロックとテーブルロックの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: ubuntu20.04 上の CLion2020.1.3 での ROS のインストールと設定の詳細な説明
>>: Ubuntu16.04にclionをインストールするプロセス全体と手順の詳細な説明
このセクションでは、テキストの変更の詳細から始めます。これにより、読者はさまざまな HTML フォン...
CentOS 8 ではソフトウェア パッケージのインストール プログラムが変更され、yum 構成方法...
日常の開発タスクでは、データ テーブル内のグループ化フィールドに基づいて統計データを取得するために、...
この記事では、モバイルモーダルボックス効果を実現するためのJavaScriptの具体的なコードを参考...
トランザクションは、複数の SQL ステートメントの原子性、つまり、それらが一緒に完了するか、一緒に...
クエリで EXPLAIN を実行するとデータベースが変更されるかどうかを尋ねられた場合、おそらく「い...
序文Linux には Windows のような目立つごみ箱がないため、簡単に復元することはできません...
MySQL の遅いクエリの説明MySQL スロー クエリ ログは、MySQL が提供するログ レコー...
インストール手順 rpm -ivh mysql-コミュニティ-共通-5.7.18-1.el7.x86...
目次1. JavaScriptはページ内のすべてのHTML要素を変更できる1. IDでHTML要素を...
コードをコピーコードは次のとおりです。 <object classid="clsid...
VMware Workstation は、開発、テスト、デモンストレーション、展開のために仮想マシン...
必要:ビジネス要件によると、写真をアップロードできる必要があり、アップロードされた写真はモバイル端末...
目次序文yumソース、epelソースを設定するCephソースの設定Cephとそのコンポーネントをイン...
<br />元の記事: http://www.alistapart.com/articl...