序文 データベース操作では、同時データ読み取りの正確性を効果的に保証するために、トランザクション分離レベルが提案されています。データベーストランザクションには 4 つの分離レベルがあります。以下では詳細には触れません。詳細な紹介を見てみましょう。 データベース トランザクションには 4 つの分離レベルがあります。
トランザクション分離の概念を初めて知る人は、上記の教科書的な定義に戸惑うかもしれません。以下では、具体的な例を通して 4 つの分離レベルについて説明します。 まず、ユーザー テーブルを作成します。 テーブルユーザーの作成 ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, 主キー (`id`)、 一意の `uniq_name` USING BTREE (name) ) ENGINE=`InnoDB` AUTO_INCREMENT=10 デフォルト文字セット utf8 COLLATE utf8_general_ci; コミットされていない読み取り分離レベル まず、トランザクション分離レベルをコミット済みの読み取りに設定します。 mysql> セッショントランザクション分離レベルをコミットされていない読み取りに設定します。 クエリは正常、影響を受けた行は 0 行 (0.00 秒) mysql> @@session.tx_isolation を選択します。 +------------------------+ | @@session.tx_isolation | +------------------------+ | 読み取り未コミット | +------------------------+ セット内の 1 行 (0.00 秒) 以下では、2 つのターミナルを開いて、それぞれトランザクション 1 とトランザクション 2 をシミュレートします。ps: 操作 1 と操作 2 は、時系列順に実行されることを意味します。 取引 1 mysql> トランザクションの開始; # 操作 1 クエリは正常、影響を受けた行は 0 行 (0.00 秒) mysql> insert into user(name) values('ziwenxie'); # 操作 3 クエリは正常、1 行が影響を受けました (0.05 秒) 取引2 mysql> トランザクションを開始; # 操作 2 クエリは正常、影響を受けた行は 0 行 (0.00 秒) mysql> select * from user; # 操作4 +----+----------+ | ID | 名前 | +----+----------+ | 10 | ziwenxie | +----+----------+ セット内の 1 行 (0.00 秒) 上記の実行結果から、コミットされていない読み取りレベルでは、トランザクション 2 でコミットされていないデータがトランザクション 1 で読み取られる可能性があることが明確にわかります。これはダーティ リードです。 コミット読み取り分離レベル 上記のダーティ リード問題は、分離レベルをコミットに設定することで解決できます。 mysql> セッショントランザクション分離レベルを読み取りコミット済みに設定します。 取引 1 mysql> start transaction; # 操作 1 クエリ OK、影響を受けた行数 0 (0.00 秒) mysql> select * from user; # 操作 3+----+----------+ | ID | 名前 | +----+----------+ | 10 | ziwenxie | +----+----------+ セット内の 1 行 (0.00 秒) mysql> select * from user; # 操作 5. 操作 4 の変更はトランザクション 1 には影響しません+----+----------+ | ID | 名前 | +----+----------+ | 10 | ziwenxie | +----+----------+ セット内の 1 行 (0.00 秒) mysql> select * from user; # 操作 7+----+------+ | ID | 名前 | +----+------+ | 10 | リシ | +----+------+ セット内の 1 行 (0.00 秒) mysql> commit; # 操作 8 クエリ OK、影響を受けた行数 0 (0.00 秒) 取引2 mysql> start transaction; # 操作 2 クエリ OK、影響を受けた行数 0 (0.00 秒) mysql> update user set name='lisi' where id=10; # 操作 4 クエリ OK、1 行が影響を受けました (0.06 秒) 一致した行: 1 変更された行: 1 警告: 0 mysql> commit; # 操作 6 クエリ OK、影響を受けた行数 0 (0.08 秒) ダーティ リード問題は解決されましたが、トランザクション 1 の操作 7 では、トランザクション 2 の操作 6 がコミットされた後、同じトランザクションでトランザクション 1 によって 2 回読み取られたデータが異なることに注意してください。これが非反復読み取り問題です。3 番目のトランザクション分離レベルである反復読み取りを使用すると、この問題を解決できます。 繰り返し読み取り分離レベル MySQL の Innodb ストレージ エンジンのデフォルトのトランザクション分離レベルは繰り返し読み取り分離レベルであるため、追加の設定を行う必要はありません。 取引 1 mysql> start tansactoin; # 操作 1mysql> select * from user; # 操作 5+----+----------+ | ID | 名前 | +----+----------+ | 10 | ziwenxie | +----+----------+ セット内の 1 行 (0.00 秒) mysql> commit; # 操作 6 クエリ OK、影響を受けた行数 0 (0.00 秒) mysql> select * from user; # 操作 7+----+------+ | ID | 名前 | +----+------+ | 10 | リシ | +----+------+ セット内の 1 行 (0.00 秒) 取引2 mysql> start tansactoin; # 操作 2mysql> update user set name='lisi' where id=10; # 操作 3クエリ OK、1 行が影響を受けました (0.00 秒) 一致した行: 1 変更された行: 1 警告: 0 mysql> commit; # 操作4 トランザクション 1 の操作 5 では、操作 3 のトランザクション 2 の更新を読み取りませんでした。コミット後に更新されたデータのみを読み取ることができます。 Innodb はファントム リードを解決しますか? 実は、RR レベルでファントム リードが発生することがあります。InnoDB エンジンは、この問題は MVCC マルチバージョン同時実行制御を使用することで解決されると公式に主張しています。InnoDB が本当にファントム リードを解決するのか検証してみましょう。 表示の便宜上、上記のユーザー テーブルを変更しました。 mysql> テーブルユーザーを変更し、給与を追加します int(11); クエリは正常、影響を受けた行は 0 行 (0.51 秒) レコード: 0 重複: 0 警告: 0 mysql> ユーザーから削除します。 クエリは正常、1 行が影響を受けました (0.07 秒) mysql> ユーザー(名前、給与)に値('ziwenxie'、88888888);を挿入します。 クエリは正常、1 行が影響を受けました (0.07 秒) mysql> ユーザーから * を選択します。 +----+----------+----------+ | ID | 名前 | 給与 | +----+----------+----------+ | 10 | ziwenxie | 88888888 | +----+----------+----------+ セット内の 1 行 (0.00 秒) 取引 1 mysql> start transaction; # 操作 1 クエリ OK、影響を受けた行数 0 (0.00 秒) mysql> update user set salary='4444'; # 操作 6 は実際には 2 つの行に影響を与えました。ファントム リードは解決されませんでしたか? クエリは正常、2 行が影響を受けました (0.00 秒) 一致した行: 2 変更された行: 2 警告: 0 mysql> select * from user; # 操作 7、Innodb はファントムリードを完全には解決しません +----+----------+--------+ | ID | 名前 | 給与 | +----+----------+--------+ | 10 | ziwenxie | 4444 | | 11 | 張三 | 4444 | +----+----------+--------+ セット内の 2 行 (0.00 秒) mysql> commit; # 操作 8 クエリ OK、影響を受けた行数 0 (0.04 秒) 取引2 mysql> start transaction; # 操作 2 クエリ OK、影響を受けた行数 0 (0.00 秒) mysql> insert into user(name, salary) value('zhangsan', '666666'); # 操作 4 クエリ OK、1 行が影響を受けました (0.00 秒) mysql> commit; # 操作 5 クエリ OK、影響を受けた行数 0 (0.04 秒) 上記の例から、Innodb は公式に主張されているようにファントム リードを解決しないことがわかりますが、上記のシナリオはあまり一般的ではなく、あまり心配する必要はありません。 シリアル化可能な分離レベル すべてのトランザクションは最高の分離レベルでシリアルに実行され、ファントム リードは発生しません。パフォーマンスは非常に低下するため、実際の開発ではほとんど使用されません。 要約する 上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に少しでもお役に立てれば幸いです。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM をご愛顧いただき、ありがとうございます。 以下もご興味があるかもしれません:
|
<<: Alibaba Cloud で静的ウェブサイトを素早く構築する方法
>>: eject を使用せずに create-react-app の設定を変更する方法
多くのアプリやウェブサイトでは、ログインやアカウント登録の際にSMS認証コード1を送信する場所があり...
フィルターを使用して画像に透明な CSS を書く方法コードをコピーコードは次のとおりです。 html...
<br />テーブルは、昔から誰もが使ってきたタグで、今も使われています。しかし、現在の...
この記事では、年、月、日の3段階のリンクを実現するためのJavaScriptの具体的なコードを参考ま...
React は、ユーザー インターフェイスを構築するための JavaScript ライブラリです。 ...
この記事では、例を使用して、MySQL ビューの原理と基本操作を説明します。ご参考までに、詳細は以下...
FileZilla Serverをサーバーにインストールすると、425データ接続を開けない問題が発生...
Centos7はyumを使用してMySQLをインストールし、リモート接続を実現する方法です。MySQ...
この記事では、参考までに、虫眼鏡のJavaScriptオブジェクト指向実装の具体的なコードを紹介しま...
第1章: keepalivedの紹介VRRP プロトコルの目的は、静的ルーティングの単一点障害問題を...
以前、動的フォームを記述しているときに落とし穴に遭遇しました。インデックスの添え字をキーとして使用す...
目次複数の変数を同時に宣言する場合は、1 行に短縮できます。分割代入は複数の変数に同時に値を割り当て...
まず、SFTP プロトコルと FTP プロトコルの違いを理解してください。ここでは詳細には触れません...
平行ボックスの余白 (二重余白の重なり) に関する面接の質問: 1 つのボックスに上余白があり、もう...
ビューポートとはモバイル ブラウザは、Web ページを仮想の「ウィンドウ」(ビューポート) に配置し...