MySQLトランザクションの基本的な学習と経験の共有

MySQLトランザクションの基本的な学習と経験の共有

トランザクションは、論理的な操作のグループです。この操作グループを構成する各ユニットは、成功するか失敗するかのいずれかになります。この機能はトランザクションと呼ばれます。MySQL トランザクションを学ぶためのヒントをいくつか紹介します。

取引の特徴

1. アトミック性: アトミック性とは、トランザクションが分割できない作業単位であり、トランザクション内の操作はすべて実行されるか、まったく実行されないかのいずれかであることを意味します。

2. 一貫性: トランザクションでは、トランザクションの前後のデータの整合性が一貫している必要があります。銀行振込や電車の切符の購入などがこれにあたります。

3. 分離: 複数のトランザクション。トランザクションの分離とは、複数のユーザーが同時にデータベースにアクセスする場合、あるユーザーのトランザクションが他のユーザーのトランザクションによって妨害されることがなく、複数の同時トランザクション間のデータが互いに分離されている必要があることを意味します。

4. 耐久性: 耐久性とは、トランザクションがコミットされると、データベース内のデータに加えられた変更が永続的であり、データベースに障害が発生しても、何ら影響を受けないことを意味します。

これらの概念について書くのは少し混乱します。とにかく回り込んでください!とにかく、それは私のルールではなく、公式のものであり、説明は私が作り上げたものです! ! !

トランザクションの同時アクセスの問題

分離の問題を考慮しない場合、トランザクションには 3 種類の同時アクセスの問題があります。

1. ダーティ リード: トランザクションでデータを読み取るときに、別のトランザクションからのコミットされていないデータが読み取られます。

たとえば、アカウント A が 1 元をアカウント B に送金しましたが、A はトランザクションをコミットしません。アカウント B はダーティ リードを通じてそれを認識します。この時点で、B は A が送金したと考えますが、この時点でアカウント A はトランザクションをロールバックします。実際はBさんにお金は振り込まれていなかったのですが、Bさん自身がAさんが振り込んだと思っていたようです。ちょっとややこしいですね。私の説明のせいでしょうか!

コードを見てみましょう:

アカウントを更新し、money=money+1 を name='B' に設定します。 --A は B に通知します。
アカウントを更新します。set money=money -1 where name='A';

2. 反復不可能な読み取り: トランザクションで 2 回読み取られたデータの内容は不一致です。これは、クエリ間に時間間隔があり、データが別のトランザクションによって変更されて送信されているため、問題が発生します。

3. ファントム リード/仮想リード: トランザクションで 2 回読み取られたデータの量が不一致です。

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

上記では、3 種類のトランザクション同時実行性の問題を紹介しました。それではデータベースが提供するソリューションを紹介しましょう。

1.read uncommitted: コミットされていないデータを読み取ります。これは最も低いレベルですが、間違いなく最も効率的です。ただし、問題を解決することはできません。

2.コミットされたデータの読み取り: コミットされたデータの読み取り: ダーティ リードを解決できます。

3.繰り返し読み取り: 繰り返し読み取り: ダーティ読み取りと繰り返し不可能な読み取りを解決できます。

4.serializable: シリアル化: ダーティ リード、非反復リード、仮想リードを解決できます。効率は最も悪く、テーブルをロックするのと同じです。通常、開発では使用されません。

上記の「2」はOracleデータベースのデフォルト設定であり、「3」はMySQLデータベースのデフォルト設定です。

次に、上記のさまざまなトランザクション分離レベルでの MySQL データベースのデモンストレーションについて説明します。

まず、2つの文法を紹介します。

1. MySQLデータベースのデフォルトの分離レベルを表示します: @@tx_isolationを選択します

図に示すように:

2. MySQLの分離レベルを設定する: セッショントランザクション分離レベルを設定するトランザクション分離レベル

図に示すように:

トランザクション分離レベルのデモンストレーション

注意: 自分自身をシミュレートする場合は、2 つの MySQL クライアントを開いて、つまり 2 人のユーザーをシミュレートする必要があります。

1. コミットされていない読み取り

図に示すように:

構文を使用して、データベースのトランザクション分離レベルをコミットされていない読み取りに変更しました。

まずアカウントテーブルがあります。

図に示すように:ウィンドウ1

ウィンドウ 2

データベース テーブル内の元のデータ money は 5000 です。トランザクションを開始すると、zhangsan のアカウントに 1000 が追加され、lisi のアカウントから 1000 が減額されました。ただし、トランザクションはまだコミットされていません。ただし、データベース テーブルを再度クエリすると、データが変更されていました。これはダーティ リードであり、繰り返し不可能なリードです。

ファントムリーディング/バーチャルリーディングも存在するという事実を隠しません!

2.コミットされた読み取り

図に示すように:

データベースのトランザクション分離をコミット済みの読み取りに変更しました。

上記の表は以下の通りです。

図に示すように:ウィンドウ1

ウィンドウ 2

データベース テーブル zhangsan のアカウントの金額とアカウント lisi の金額が変更されました。トランザクションをコミットしませんでした。別のウィンドウでトランザクションを開いた状態でクエリを実行したところ、ダーティ リードは発生しませんでした。ただし、トランザクションをコミットし、別のウィンドウでトランザクションの下で再度クエリを実行したところ、非反復読み取りが発生しました。これによりダーティ リードは回避できますが、クエリ中に非反復読み取りとファントム読み取り/仮想読み取りが発生しました。

3. 繰り返し読み取り

図に示すように:

データベースのトランザクション分離をコミット済みの読み取りに変更しました。

上記の表は以下の通りです。

図に示すように:ウィンドウ1

ウィンドウ 2

両方のウィンドウでトランザクションを開きました。ウィンドウ 1 でデータ操作を実行してトランザクションをコミットした後、トランザクションが開いている間にウィンドウ 2 のデータを照会しました。ウィンドウ 1 にはデータ操作レコードが見つかりませんでした。これにより、ダーティ リードと反復不可能な読み取りが回避されました。

誤読や幻読も回避できると言う人もいますが、そうではありません。

写真をご覧ください:

lisi アカウントを操作したときは、データのみが変更されました。しかし、wangwu アカウントを変更したとき、クエリを実行すると wangwu アカウントのデータが表示されました。しかし、実際には、操作する前は、wangwu アカウントのデータをクエリすることはできませんでした。これがファントムリーディング/バーチャルリーディングです!

ファントム リードについて理解できない場合は、InnoDB を確認してください。

4.シリアル化可能

デモはしません。開発には推奨されませんし、遅いですが、すべての問題を回避できます。 !

総括する

トランザクション分離レベルのパフォーマンス:

コミットされていない読み取り>コミットされた読み取り>繰り返し可能な読み取り>シリアル化可能

トランザクション分離レベルのセキュリティ:

コミットされていない読み取り < コミットされた読み取り < 繰り返し可能な読み取り < シリアル化可能な読み取り

mysql トランザクション制御:

トランザクションの開始: トランザクションを開始します。

送信: コミット;

ロールバック: ロールバック;

以下もご興味があるかもしれません:
  • MySQLの基礎知識学習ノート
  • MySQL のテーブル サブクエリと相関サブクエリの基本学習チュートリアル
  • MySQL のトリガーに関する基礎学習チュートリアル
  • MySQLの基本を学ぶ MySQLコマンドを簡単に学ぶ
  • MySQLを学んだ後のまとめ(基礎編)
  • MySQLの基本を素早く学ぶ

<<:  Linuxの一般ユーザー向けスケジュールタスクの詳細な説明

>>:  Vueはログイン時に画像認証コードを実装します

推薦する

docker run によって起動されたコンテナがハングしてデータが失われた場合の対処方法

シナリオの説明あるシステムでは、機能サービスはdocker stack deploy xxxで起動し...

インターネットウェブデザインにおけるバイオニックデザインの簡単な紹介

バイオニックデザインといえば、飛行機の発明、ドバイのブルジュ・アル・アラブ、平泳ぎなどを思い浮かべる...

vue3 watch と watchEffect の使い方と違い

1.リスナーを見る時計のご紹介 'vue' から { ref, reactive, ...

nginx.conf ファイルの構文強調表示とフォーマット設定には nginx.vim ツールを使用します。

私はtengineを使用しています。インストールディレクトリは/usr/local/tengineで...

HTML テーブル マークアップ チュートリアル (10): セル パディング属性 CELLPADDING

セルのパディングは、セルの内容と境界線の間の距離です。基本的な構文<TABLE セルパディング...

Linux ネットワークプログラミング機能の簡単な分析

目次1.ソケットを作成する2. ソケットをバインドする3. 聞き手を作る。聞く4. 接続が受け入れら...

MySQL スケジュールタスク例チュートリアル

序文MySQL 5.1.6 以降、非常にユニークな機能であるイベント スケジューラが追加されました。...

JavaScript での実行コンテキストと実行スタックの例の説明

JavaScript - 原則シリーズ日常の開発では、既存のプロジェクトを引き継ぐときは常に、まず他...

Docker コンテナ ソース コードのデプロイ httpd ストレージ ボリュームを使用して Web サイトをデプロイする (推奨)

目次Dockerコンテナのソースコードを使用してhttpdをデプロイし、ストレージボリュームを使用し...

Zabbix ベースの Jenkins プロセス監視の詳細な説明

1. 監視アーキテクチャ図 2. 実装のアイデアJenkins に Metrics プラグインをイン...

HTML チュートリアル: 順序なしリスト

<br />原文: http://andymao.com/andy/post/102.h...

nginxディレクトリパスをリダイレクトする方法

ドメイン名に続くパスがデフォルトの Web ディレクトリではなく、ローカル ディスク上の他のディレク...

JSON.stringify を使用する際に発生する循環参照の問題を解決する方法の詳細な説明

プログラマーが日常的に TypeScript/JavaScript 開発を行う場合、複雑な Java...

入力タイプ=テキスト値=str を使用するための不完全なソリューション

今日、非常に奇妙な問題に遭遇しました。次のコードを見てください。 SimpleDateFormat ...

Nginxを再コンパイルしてモジュールを追加する方法

Nginx をコンパイルしてインストールするときに、http_ssl_module などの一部のモジ...