MySQL のトランザクション分離レベルの簡単な分析とその実装原則の説明
この記事では、MySQL のトランザクションを理解し、トランザクション分離の実装原理について説明します。お役に立てば幸いです。
データベース トランザクションと言えば、トランザクションの ACID 特性、分離レベル、解決された問題など、多くのトランザクション関連の知識が誰の頭にも容易に浮かぶはずです。 (ダーティ リード、ノンリピータブル リード、ファントム リード) などがありますが、トランザクションのこれらの機能がどのように実装されているか、およびなぜ 4 つの分離レベルがあるのかを実際に知っている人はほとんどいないかもしれません。
今日はまず、MySQL におけるトランザクション分離の実装原理について説明し、引き続き他の機能の実装原理を分析する記事を公開していきます。
もちろん、MySQL は広範囲かつ奥が深いため、記事の省略は避けられません。批判や修正は歓迎です。
説明
MySQL のトランザクション実装ロジックはエンジン層にあり、すべてのエンジンがトランザクションをサポートしているわけではありません。次の手順は InnoDB エンジンに基づいています。
定義
分離とは、さまざまなトランザクションが次々に送信されて実行された後、最終的な影響は連続的であるという事実を指します。つまり、トランザクションの場合、それは実行中です。このプロセスでは、認識されるデータの変更は自分自身の操作によってのみ発生する必要があり、他のトランザクションによってデータの変更が発生してはなりません。
分離により、同時トランザクションの問題が解決されます。
標準 SQL 分離レベル
分離を実装する最も簡単な方法は、各トランザクションをシリアルに実行することです。前のトランザクションが完了していない場合、後続のトランザクションは待機します。ただし、この実装方法は明らかに同時実行効率が低く、実際の環境での使用には適していません。
上記の問題を解決し、さまざまなレベルの同時実行制御を実現するために、SQL 標準の作成者は、非コミット読み取り (コミットされていない読み取り)、コミット読み取り (コミットされた読み取り)、反復可能読み取り (反復可能) 読み取りというさまざまな分離レベルを提案しました。 )、シリアル化された読み取り (シリアル化可能)。最も高度な分離レベルはシリアル化読み取りであり、他の分離レベルではトランザクションが同時に実行されるため、ある程度の問題は許容されます。次のマトリックス表を参照してください。
#分離レベル (: 表示を許可、-: 表示を許可しない) | ダーティ リード | ##繰り返し不可能なリード##ファンタジー リード | ## ## |
---|
実装方法 | |
---|---|
トランザクションは現在読み取られているデータをロックしません; | トランザクションは現在、特定のデータを更新しています大量のデータ (つまり、更新が発生した瞬間) を処理するには、最初に 行レベルの共有ロック をデータに追加する必要があります。この共有ロックは、トランザクションが終了するまで解放されません。 |
トランザクションは、現在読み取られているデータに | 行レベルの共有ロックを追加します (読み取り時のみロックされます)、行が読み取られると、行レベルの共有ロックはすぐに解放されます。トランザクションが特定のデータを更新した瞬間 (つまり、更新が発生した瞬間)、最初に row を追加する必要があります。 -レベルの排他ロック 、トランザクションが終了するまで解放されません。 |
トランザクションが特定のデータを読み取る瞬間 (読み取りを開始する瞬間)、まずそのデータに | 行を追加する必要があります。 レベル共有ロックはトランザクションが終了するまで解放されません; トランザクションが特定のデータを更新した瞬間(つまり、更新が発生した瞬間)、最初に 行レベルの排他ロックを追加する必要があります。 lock 、トランザクションが終了するまで解放されません。 |
トランザクションがデータを読み取るときは、トランザクションが終了するまで、まず | テーブル レベルの共有ロックを追加する必要があります。 トランザクションがデータを更新するときは、まず テーブル レベルの排他ロック を追加する必要があります。このロックはトランザクションが終了するまで解放されません。 |
事务隔离级别 | 实现方式 |
---|---|
未提交读(RU) | 事务对当前被读取的数据不加锁,都是当前读; 事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级共享锁,直到事务结束才释放。 |
提交读(RC) | 事务对当前被读取的数据不加锁,且是快照读; 事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁(Record),直到事务结束才释放。 |
可重复读(RR) | 事务对当前被读取的数据不加锁,且是快照读; 事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁(Record,GAP,Next-Key),直到事务结束才释放。 通过间隙锁,在这个级别MySQL就解决了幻读的问题 通过快照,在这个级别MySQL就解决了不可重复读的问题 |
序列化读(S) | 事务在读取数据时,必须先对其加表级共享锁 ,直到事务结束才释放,都是当前读; 事务在更新数据时,必须先对其加表级排他锁 ,直到事务结束才释放。 |
可以看到,InnoDB通过MVCC很好的解决了读写冲突的问题,而且提前一个级别就解决了标准级别下会出现的幻读问题,大大提升了数据库的并发能力。
一些常见误区
幻读到底包不包括了delete的情况?
不可重复读:前后多次读取一行,数据内容不一致,针对其他事务的update和delete操作。为了解决这个问题,使用行共享锁,锁定到事务结束(也就是RR级别,当然MySQL使用MVCC在RC级别就解决了这个问题)
幻读:当同一个查询在不同时间生成不同的行集合时就是出现了幻读,针对的是其他事务的insert操作,为了解决这个问题,锁定整个表到事务结束(也就是S级别,当然MySQL使用间隙锁在RR级别就解决了这个问题)
网上很多文章提到幻读和提交读的时候,有的说幻读包括了delete的情况,有的说delete应该属于提交读的问题,那到底真相如何呢?我们实际来看下MySQL的官方文档(如下)
The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a
SELECT
) is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.https://dev.mysql.com/doc/refman/5.7/en/innodb-next-key-locking.html
可以看到,幻读针对的是结果集前后发生变化,所以看起来delete的情况应该归为幻读,但是我们实际分析下上面列出的标准SQL在RR级别的实现原理就知道,标准SQL的RR级别是会对查到的数据行加行共享锁,所以这时候其他事务想删除这些数据行其实是做不到的,所以在RR下,不会出现因delete而出现幻读现象,也就是幻读不包含delete的情况。
MVCC能解决了幻读问题?
网上很多文章会说MVCC或者MVCC+间隙锁解决了幻读问题,实际上MVCC并不能解决幻读问题。如以下的例子:
begin; #假设users表为空,下面查出来的数据为空 select * from users; #没有加锁 #此时另一个事务提交了,且插入了一条id=1的数据 select * from users; #读快照,查出来的数据为空 update users set name='mysql' where id=1;#update是当前读,所以更新成功,并生成一个更新的快照 select * from users; #读快照,查出来id为1的一条记录,因为MVCC可以查到当前事务生成的快照 commit;
可以看到前后查出来的数据行不一致,发生了幻读。所以说只有MVCC是不能解决幻读问题的,解决幻读问题靠的是间隙锁。如下:
begin; #假设users表为空,下面查出来的数据为空 select * from users lock in share mode; #加上共享锁 #此时另一个事务B想提交且插入了一条id=1的数据,由于有间隙锁,所以要等待 select * from users; #读快照,查出来的数据为空 update users set name='mysql' where id=1;#update是当前读,由于不存在数据,不进行更新 select * from users; #读快照,查出来的数据为空 commit; #事务B提交成功并插入数据
注意,RR级别下想解决幻读问题,需要我们显式加锁,不然查询的时候还是不会加锁的。
原文地址:https://segmentfault.com/a/1190000025156465
作者: X先生
【相关推荐:mysql视频教程】
以上がMySQL のトランザクション分離レベルの簡単な分析とその実装原則の説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









次の手順でphpmyadminを開くことができます。1。ウェブサイトコントロールパネルにログインします。 2。phpmyadminアイコンを見つけてクリックします。 3。MySQL資格情報を入力します。 4.「ログイン」をクリックします。

MySQLはオープンソースのリレーショナルデータベース管理システムであり、主にデータを迅速かつ確実に保存および取得するために使用されます。その実用的な原則には、クライアントリクエスト、クエリ解像度、クエリの実行、返品結果が含まれます。使用法の例には、テーブルの作成、データの挿入とクエリ、および参加操作などの高度な機能が含まれます。一般的なエラーには、SQL構文、データ型、およびアクセス許可、および最適化の提案には、インデックスの使用、最適化されたクエリ、およびテーブルの分割が含まれます。

Redisは、単一のスレッドアーキテクチャを使用して、高性能、シンプルさ、一貫性を提供します。 I/Oマルチプレックス、イベントループ、ノンブロッキングI/O、共有メモリを使用して同時性を向上させますが、並行性の制限、単一の障害、および書き込み集約型のワークロードには適していません。

データベースとプログラミングにおけるMySQLの位置は非常に重要です。これは、さまざまなアプリケーションシナリオで広く使用されているオープンソースのリレーショナルデータベース管理システムです。 1)MySQLは、効率的なデータストレージ、組織、および検索機能を提供し、Web、モバイル、およびエンタープライズレベルのシステムをサポートします。 2)クライアントサーバーアーキテクチャを使用し、複数のストレージエンジンとインデックスの最適化をサポートします。 3)基本的な使用には、テーブルの作成とデータの挿入が含まれ、高度な使用法にはマルチテーブル結合と複雑なクエリが含まれます。 4)SQL構文エラーやパフォーマンスの問題などのよくある質問は、説明コマンドとスロークエリログを介してデバッグできます。 5)パフォーマンス最適化方法には、インデックスの合理的な使用、最適化されたクエリ、およびキャッシュの使用が含まれます。ベストプラクティスには、トランザクションと準備された星の使用が含まれます

MySQLは、そのパフォーマンス、信頼性、使いやすさ、コミュニティサポートに選択されています。 1.MYSQLは、複数のデータ型と高度なクエリ操作をサポートし、効率的なデータストレージおよび検索機能を提供します。 2.クライアントサーバーアーキテクチャと複数のストレージエンジンを採用して、トランザクションとクエリの最適化をサポートします。 3.使いやすく、さまざまなオペレーティングシステムとプログラミング言語をサポートしています。 4.強力なコミュニティサポートを提供し、豊富なリソースとソリューションを提供します。

Apacheはデータベースに接続するには、次の手順が必要です。データベースドライバーをインストールします。 web.xmlファイルを構成して、接続プールを作成します。 JDBCデータソースを作成し、接続設定を指定します。 JDBC APIを使用して、接続の取得、ステートメントの作成、バインディングパラメーター、クエリまたは更新の実行、結果の処理など、Javaコードのデータベースにアクセスします。

DockerでMySQLを起動するプロセスは、次の手順で構成されています。MySQLイメージをプルしてコンテナを作成および起動し、ルートユーザーパスワードを設定し、ポート検証接続をマップしてデータベースを作成し、ユーザーはすべての権限をデータベースに付与します。

CentOSにMySQLをインストールするには、次の手順が含まれます。適切なMySQL Yumソースの追加。 yumを実行して、mysql-serverコマンドをインストールして、mysqlサーバーをインストールします。ルートユーザーパスワードの設定など、MySQL_SECURE_INSTALLATIONコマンドを使用して、セキュリティ設定を作成します。必要に応じてMySQL構成ファイルをカスタマイズします。 MySQLパラメーターを調整し、パフォーマンスのためにデータベースを最適化します。
