ホームページ データベース mysql チュートリアル MySQL のトランザクションとロック

MySQL のトランザクションとロック

Feb 06, 2017 am 11:12 AM

この記事では、データベースのトランザクションとロックに関する関連知識を詳しく紹介します。主にいくつかの概念的なことは退屈に思えるかもしれませんが、資格のあるプログラマーとして、それらを習得する必要がありますし、そうしなければなりません。この理論的な知識は、私たちが普段コードを書くときの内面の強さのようなものであり、内面と外面の両方のスキルを練習し、お互いを高め合うことによってのみ、武道の達人のレベルに達することができます。さて、早速始めましょう。

データベーストランザクション

トランザクションの境界

トランザクションの開始境界(開始)
トランザクションの終了境界(コミット): トランザクションを送信し、トランザクションによって更新されたデータベースの状態を永続的に保存します。
トランザクションの異常終了境界(ロールバック):トランザクションを取り消し、データベースをトランザクション実行前の初期状態に戻します。

MySQL.exe プログラムを起動するたびに、別のデータベース接続が確立されます。各データベース接続には、現在のトランザクション モードを表すグローバル変数 autocommit があり、これには 2 つのオプションの値があります:

  • 0: 手動コミット モードを表します

  • 1: 自動コミット モードを表し、デフォルト値

Weこの値を表示および変更できます。

データベーストランザクション (ACID) の 4 つの特性:

  • 原子性: トランザクションはアトミックな操作単位であり、データに対する変更はすべて実行されるか、まったく実行されないかのいずれかです。

  • 一貫性 一貫性: データは維持される必要があります。トランザクションの開始時と完了時の一貫性。

  • 分離: データベース システムは、トランザクションが外部の同時実行から「独立」していることを保証します。

  • 持続性: トランザクションの完了後。 、データへの変更は永続的であり、システム障害が発生した場合でも維持できます。

トランザクション分離レベル

データベーストランザクション分離レベルは、トランザクションが他のトランザクションの中間結果を読み取ることができるかどうかのみを意味します。

MySQL のトランザクションとロック

  • Read Uncommitted (コミットされていないコンテンツの読み取り)
    この分離レベルでは、すべてのトランザクションは他のコミットされていないトランザクションの実行結果を確認できます。この分離レベルは他のレベルと比べてパフォーマンスがそれほど優れていないため、実際のアプリケーションではほとんど使用されません。コミットされていないデータの読み取りは、ダーティ リードとも呼ばれます。

  • Read Committed
    これは、ほとんどのデータベース システムのデフォルトの分離レベルです (ただし、MySQL のデフォルトではありません)。これは分離の単純な定義を満たしています。つまり、トランザクションはコミットされたトランザクションによって行われた変更のみを確認できます。この分離レベルは、いわゆる非反復読み取りもサポートします。これは、同じトランザクションの他のインスタンスがこのインスタンスの処理中に新しいコミットを持つ可能性があるため、同じ選択が異なる結果を返す可能性があるためです。

  • Repeatable Read
    これは、MySQL のデフォルトのトランザクション分離レベルであり、データを同時に読み取るときに、同じトランザクションの複数のインスタンスが同じデータ行を参照できるようにします。ただし、理論的には、これはファントム リード (ファントム リード) という別のやっかいな問題につながります。簡単に言えば、ファントム読み取りとは、ユーザーが特定の範囲のデータ行を読み取るときに、別のトランザクションがその範囲に新しい行を挿入することを意味します。ユーザーがその範囲内のデータ行を再度読み取ると、新しい行があることがわかります。 " わかりました。 InnoDB および Falcon ストレージ エンジンは、Multiversion Concurrency Control (MVCC) メカニズムを通じてこの問題を解決します。

  • シリアル化可能
    これは、トランザクションが互いに競合しないように強制的に順序付けすることで、ファントム読み取りの問題を解決します。つまり、読み取られた各データ行に共有ロックが追加されます。このレベルでは、多数のタイムアウトやロック競合が発生する可能性があります。

分離レベルが高くなるほど、データの完全性と一貫性が保証されますが、同時実行パフォーマンスへの影響は大きくなります。ほとんどのアプリケーションでは、データベース システムの分離レベルを Read Committed に設定することを効果的に検討できます。これにより、ダーティ リードが回避され、同時実行パフォーマンスが向上します。これにより、反復不可能な読み取り、無駄な更新、第 2 タイプの更新の喪失などの同時実行性の問題が発生しますが、そのような問題が発生する可能性がある個別の状況では、アプリケーションが悲観的ロックと楽観的ロックを使用して制御できます。

トランザクションの伝播

  1. PROPAGATION_REQUIRED

    現在実行中のトランザクションを追加します。現在のトランザクションが存在しない場合は、新しいトランザクションを開始します。 Spring オペレーティング データベースのデフォルトのトランザクション伝播動作は propagation_required です。

  2. PROPAGATION_SUPPORTS

    現在トランザクション内にある場合は、トランザクションとして実行されます。

  3. PROPAGATION_MANDATORY

    トランザクション内で実行する必要があります。 。つまり、親トランザクションによってのみ呼び出すことができます。それ以外の場合は、例外がスローされます。

  4. PROPAGATION_REQUIRES_NEW

    現在のトランザクションを一時停止し、新しいトランザクションを開始します。

  5. PROPAGATION_NOT_SUPPORTED

    トランザクションは現在サポートされていません。トランザクション中の場合、現在のトランザクションは一時停止され、非トランザクション動作で実行されます。

  6. PROPAGATION_NEVER

    をトランザクション内で実行すると、例外がスローされます。

  7. PROPAGATION_NESTED

    ネストされたトランザクションは親トランザクションに依存します。親トランザクションがコミットされると、親トランザクションもロールバックされます。

行レベルのロック

Mysql の 3 種類のロック:

行レベル: エンジン INNODB、レコードの単一行をロック

ページ レベル: エンジン BDB、一度に隣接するレコードのグループをロックします。
テーブル レベル: エンジン MyISAM。テーブル全体をロックするものとして理解され、同時に読み取ることはできますが、書き込むことはできません。
3 種類のロックの特徴は次のように大まかに要約できます:
1) テーブルレベルのロック: 低いオーバーヘッド、高速なロック、大きなロック粒度、最も高いロック競合確率、最も低い同時実行性。
2) 行レベルのロック: オーバーヘッドが高く、ロックが遅い。ロックの粒度が最も小さく、ロックの競合の可能性が最も低く、同時実行性も最も高い。
3) ページ ロック: オーバーヘッドとロック時間はテーブル ロックと行ロックの間であり、デッドロックが発生します。ロックの粒度はテーブル ロックと行ロックの間であり、同時実行性は平均的です。

ここで主に説明しているのは、行レベルのロックです。一般に、フラッシュ セール システムでは、在庫はフラッシュ セール中に非常に重要なデータであるため、行レベルのロックを使用します。データベース テーブルを作成するときに次の設定が表示されます:

ENGINE = InnoDB AUTO_INCREMENT=10 DEFAULT CHARACTER SET = utf8 comment='用户表
ログイン後にコピー

エンジンを InnoDB に設定します。InnnoDB は他のエンジンとは異なります。まず、トランザクション (TRANCSACTION) をサポートし、次に行レベルのロックを使用します。

InnoDB中两种模式的行级锁:

1)共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
( Select * from table_name where ……lock in share mode)
2)排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和 排他写锁。(select * from table_name where…..for update)

为了允许行锁和表锁共存,实现多粒度锁机制;同时还有两种内部使用的意向锁(都是表锁),分别为意向共享锁和意向排他锁。

  • 意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。

  • 意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

注意:InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。

行级锁的优缺点

行级锁定的优点:

  • 当在许多线程中访问不同的行时只存在少量锁定冲突。

  • 回滚时只有少量的更改。

  • 可以长时间锁定单一的行。

行级锁定的缺点:

  • 比页级或表级锁定占用更多的内存。

  • 当在表的大部分数据上使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁。如果你在大部分数据上经常进行GROUP BY操作或

者必须经常扫描整个表,比其它锁定明显慢很多。

hibernate中通过行级锁实现的悲观锁。

一些例子:

假设有个表单products ,里面有id跟name二个栏位,id是主键。
1: 明确指定主键,并且有此条记录,执行row lock。若查无此记录,无lock。

SELECT * FROM products WHERE id='3' FOR UPDATE;SELECT * FROM products WHERE id='3' and name="cat" FOR UPDATE;
ログイン後にコピー

2: 无主键,执行table lock。

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;
ログイン後にコピー

3: 主键不明确,table lock。

SELECT * FROM products WHERE id<>&#39;3&#39; FOR UPDATE;
ログイン後にコピー

注意: FOR UPDATE仅适用于InnoDB,且必须在事务块(BEGIN/COMMIT)中才能生效。此外,如果A与B都对表id进行查询但查询不到记录,则A与B在查询上不会进行row锁,但A与B都会获取排它锁,此时A再插入一条记录的话则会因为B已经有锁而处于等待中,此时B再插入一条同样的数据则会抛出Deadlock found when trying to get lock; try restarting transaction。然后释放锁,此时A就获得了锁而插入成功。

以上就是MySQL中的事务与锁的内容,更多相关内容请关注PHP中文网(www.php.cn)!


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Alter Tableステートメントを使用してMySQLのテーブルをどのように変更しますか? Alter Tableステートメントを使用してMySQLのテーブルをどのように変更しますか? Mar 19, 2025 pm 03:51 PM

この記事では、MySQLのAlter Tableステートメントを使用して、列の追加/ドロップ、テーブル/列の名前の変更、列データ型の変更など、テーブルを変更することについて説明します。

MySQL接続用のSSL/TLS暗号化を構成するにはどうすればよいですか? MySQL接続用のSSL/TLS暗号化を構成するにはどうすればよいですか? Mar 18, 2025 pm 12:01 PM

記事では、証明書の生成と検証を含むMySQL用のSSL/TLS暗号化の構成について説明します。主な問題は、セルフ署名証明書のセキュリティへの影響を使用することです。[文字カウント:159]

INNODBフルテキスト検索機能を説明します。 INNODBフルテキスト検索機能を説明します。 Apr 02, 2025 pm 06:09 PM

INNODBのフルテキスト検索機能は非常に強力であり、データベースクエリの効率と大量のテキストデータを処理する能力を大幅に改善できます。 1)INNODBは、倒立インデックスを介してフルテキスト検索を実装し、基本的および高度な検索クエリをサポートします。 2)一致を使用してキーワードを使用して、ブールモードとフレーズ検索を検索、サポートします。 3)最適化方法には、単語セグメンテーションテクノロジーの使用、インデックスの定期的な再構築、およびパフォーマンスと精度を改善するためのキャッシュサイズの調整が含まれます。

人気のあるMySQL GUIツール(MySQL Workbench、PhpMyAdminなど)は何ですか? 人気のあるMySQL GUIツール(MySQL Workbench、PhpMyAdminなど)は何ですか? Mar 21, 2025 pm 06:28 PM

記事では、MySQLワークベンチやPHPMyAdminなどの人気のあるMySQL GUIツールについて説明し、初心者と上級ユーザーの機能と適合性を比較します。[159文字]

MySQLの大きなデータセットをどのように処理しますか? MySQLの大きなデータセットをどのように処理しますか? Mar 21, 2025 pm 12:15 PM

記事では、MySQLで大規模なデータセットを処理するための戦略について説明します。これには、パーティション化、シャード、インデックス作成、クエリ最適化などがあります。

ドロップテーブルステートメントを使用してMySQLにテーブルをドロップするにはどうすればよいですか? ドロップテーブルステートメントを使用してMySQLにテーブルをドロップするにはどうすればよいですか? Mar 19, 2025 pm 03:52 PM

この記事では、ドロップテーブルステートメントを使用してMySQLのドロップテーブルについて説明し、予防策とリスクを強調しています。これは、バックアップなしでアクションが不可逆的であることを強調し、回復方法と潜在的な生産環境の危険を詳述しています。

外国の鍵を使用して関係をどのように表現しますか? 外国の鍵を使用して関係をどのように表現しますか? Mar 19, 2025 pm 03:48 PM

記事では、外部キーを使用してデータベース内の関係を表すことで、ベストプラクティス、データの完全性、および避けるべき一般的な落とし穴に焦点を当てています。

JSON列にインデックスを作成するにはどうすればよいですか? JSON列にインデックスを作成するにはどうすればよいですか? Mar 21, 2025 pm 12:13 PM

この記事では、クエリパフォーマンスを強化するために、PostgreSQL、MySQL、MongoDBなどのさまざまなデータベースでJSON列にインデックスの作成について説明します。特定のJSONパスのインデックス作成の構文と利点を説明し、サポートされているデータベースシステムをリストします。

See all articles