迅速ダーティリードを理解し、反復不能読み取り、ファントム読み取り

迅速ダーティリードを理解し、反復不能読み取り、ファントム読み取り 


ACID:4つの特性を言及することは避けられないチャットサービス、データベーストランザクションへ

アトミック
一貫性の
絶縁
耐久改訂
最初にテーブルを置き、さまざまな問題、オンラインの説明がたくさんあるだろう4つの分離レベルを参照してください。無知な力を見て読んだりした後、気持ちを理解し、彼らが理解していないようでした。具体的な例は示さないので、単に自分自身にこれらの質問を再現してみてください。

√が発生し、×発生します:

汚れはまたとない分離レベルを読んファントムが読ん読み込み
(READ UNCOMMITTED)コミットされていない読ん√√√
読む×√√(コミット読み取り)コミット
反復可能読み取り(反復可能読み取り)××√
シリアライズ(直列化可能)×××
その後、合計します一般的なコマンドをのmysql(以下使用されます):

コマンドは、意味
のMySQLのバージョンを表示するために選択したバージョンを()
SELECT @@ tx_isolationビューMySQLの分離レベルの
セッション・レベルの分離レベル設定のため、設定されたセッションのトランザクション分離レベル分離レベルを
開始トランザクション開いているトランザクション
のコミットトランザクションをコミット
ROLLBACKロールは、トランザクションがバック
実証
まず、次の表に設立されました:

CREATE TABLE account`( `
 ` id` INT(2)AUTO_INCREMENT NOT NULL、
 `NAME` VARCHAR(10)は、デフォルトのNULL、
 ` balance` INT(3)DEFAULT '0'、
 PRIMARY KEY( `id`)
)= ENGINEのInnoDB DEFAULT CHARSET = = 4 AUTO_INCREMENTのutf8mb4;。
。1
2
。3
。4
。5
。6
Navicatは(他のツールライン)とは、2つのクエリタブページは2つのセッションを表しとります


まず、SELECT @@ tx_isolation、出力はMySQLのデフォルトの分離レベルが反復-READ(反復)リードであることを示し、それぞれ二つのタブページにREPEATABLE-READです。

*ダーティ読み取り
分離レベルは、コミットされていない読み取るように設定されている、以下の表にデータを


タイムクライアントAクライアントB
TlのSETセッションのトランザクション分離レベルREAD UNCOMMITTED、
トランザクション開始(オープントランザクション);
更新アカウントのSETバランス=バランス+ 1000年WHERE ID = 1;
口座からSELECT * WHERE ID = 1;。
READ UNCOMMITTEDに設定+1000アカウントに、ジョー・スミス、出力は2000である    
T2 SETトランザクション分離レベルREAD UNCOMMITTEDは、セッション、
トランザクション開始;
1から* ID =アカウントを選択し、
残高照会出力2000
T3 ROLLBACK    
T4は、コミット
。からID =アカウント1 T5 SELECT *を;
チェックは千の出力バランスをとる
2000元、結果に、ジョー・スミスが千元の給料、ジョー・スミスを作った後、彼女以上の千元を自分のアカウントをチェックし、資金調達のために、このプロセスの例の概要についてを----->金融間違いのプロセスは、トランザクションがロールバックされます。ジョー・スミスは、その後、アカウント、アカウントを確認するだけで千元を見つけたとき。

ダーティ・リードトランザクションAは、データが変更されたときを指し、そのような変更がデータベースにコミットされていない、その後、別のトランザクションBは、データにアクセスし、このデータを使用します。

----->別の例として、以下の表のデータ:


タイムクライアントAクライアントB
TlのSETセッションのトランザクション分離レベルREAD UNCOMMITTED、
トランザクション開始、
アップデートのアカウントSETバランス=バランス-1000 WHERE ID = 1;
更新アカウントのSETバランス=バランス+ 1000年WHERE ID = 2;    
T2 SETセッショントランザクションの隔離READ UNCOMMITTEDレベル、
トランザクション開始;
ID = 2口座残高から選択します。
更新アカウントのSETバランスバランス= ID = 2 -1000;
UPDATE文がブロックされている
T3 ROLLBACK    
コミットT4を
次のように、データベース内のデータを実行します

次のように説明しました:

説明する時間
Tlの1千2への転送は
、商品の千元を購入し、十分T2 2千のバランスをとるには、更新ステートメントがブロックされている
T3は、1000年の1をロールバック、2バランスバランス1が0になるとなり
T4 2首尾充電、バランス0-1000 = -1000
それが故障しているので!

*読み取り繰り返さないで
、下の表のデータをコミット読み取り分離レベルに提供され、


タイムクライアントAクライアントB
TlのSETセッショントランザクション分離レベルの読取りがコミット、
トランザクション開始;
ID = 2のアカウントからSELECT *;
;バランス出力が0であるチェックアウト    
T2 SETレベルの読取りがコミットセッションのトランザクション分離、
トランザクション開始、
アップデートのアカウントSETバランス=バランス+ ID = 2 1000;
ID = 2のアカウントからSELECT *;
COMMIT;
残高照会出力千
T3 SELECT * WHERE ID = 2のアカウントから、
コミット、
残高照会出力1000は、    
トランザクション内の手段を読んで繰り返されていない1トランザクションが1を超えていない、データの読み出し、2つの取引も、このデータにアクセスするデータを修正して提出します。次に、トランザクション1とは、このデータを読み取ります。2によるトランザクションの変更には、トランザクションデータを二度1が同じ、いわゆる非反復可能読み取りではないかもしれない読み込まれます。

もちろん、あなたはT2の期間クライアントBでID =口座残高2の変更が完了することができますが、時間をコミットしませんでした、クライアントAのクエリID =口座残高2終わり、口座残高がゼロで見つけるこの分離レベルにはない読み提出することを証明することができますダーティリードが発生します。

今、上記の例では、再読み込みどのようなプロセスを見ているでしょうか?

以下の表のデータは、分離レベルが反復可能読み取りに設定されています


タイムクライアントAクライアントB
TlのSETセッションのトランザクション分離レベル反復可能読み取り、
トランザクション開始、
口座からのSELECT * ID = 2;
残高照会の出力は0であり、    
T2 SETセッションのトランザクション分離レベル反復可能読み取り、
トランザクション開始、
アップデートのアカウントSETバランス=バランス+ ID = 2 1000;
ID = 2アカウントSELECT * FROM;
COMMIT;
残高照会出力1000年
、アカウントからWHERE ID = 2 T3 SELECT *
コミット;
残高照会0を出力    
T3における上記の例の一例を詳しく見出力時間は、それは右、再読み込みするために何を意味するのか理解するには?私たちの現在のセッションの分離レベルが反復可能読み取りに設定されている場合は、現在のセッションを繰り返すことができる読んで、結果セットには関係なく、その他の事項のが提出されていない、たびに同じ読みです。
----------しかし、反復可能読み取り分離レベルでは、マジックは問題があります読んで。

*ファントムが読み取ら
下表のデータを、分離レベルが反復可能読み取りに設定されています

読書の魔法を説明するための「高性能のMySQL」の最初のセクションには

いわゆるファントムは、読書の範囲内の取引記録時間を参照して、別のトランザクションを読んで、この範囲に新しいレコードを挿入、ときもう一度読んでのトランザクション・スコープの前のレコード、意志を魔法のラインを生成します。ファントムの問題を解決するためのInnoDBストレージエンジンは、マルチバージョン同時実行制御(MVCC)によって読み取ります。

方言について説明すると、それは、クエリトランザクション1レコードID <10であり、そして3及び提出に2つのレコードを、トランザクション2の挿入レコードIDを返しました。そして、1時にトランザクションレコードのクエリID <10、および3つのレコードを返された、優れた再現性は、それを読むと言いますか?その結果、複数のデータです。

MySQLはこの場合にはMVCCによって読み取らファントムを解決し、我々は確認することができます

タイムクライアントAクライアントB
TlのSETセッションのトランザクション分離レベル反復可能読み取り、
トランザクション開始;
SELECT COUNT(*)ID <= 10アカウントから、
出力2、    
T2 SETセッションのトランザクション分離レベル反復可能読み取り、
トランザクション開始;
INSERT INTOアカウント(ID、名前、バランス)値 ( "3"、 " 王ウー"、 "0");
SELECT COUNT(*)アカウントからID <= 10;
COMMIT;
出力3
IDアカウントからT3のSELECT COUNT(*) <= 10;
COMMIT;
2出力    
ファントムは、この場合読み出し、別の例を解決し、以下の表のデータ


タイムクライアントAクライアントB
TlのSETセッションのトランザクション分離レベル反復可能読み取り、
トランザクション開始、
口座からSELECT COUNT(*)WHERE ID = 3;
出力0;    
T2 SETセッションのトランザクション分離レベル反復可能読み取り、
トランザクション開始;
INSERT INTOアカウント( ID、名前、バランス)値( "3"、 " 王ウー"、 "0");
COMMIT;
T3 INSERT INTOアカウント(ID、名前、バランス)値( "3"、 " 王呉"、 "0") ;
;主キーを繰り返して、挿入が失敗した    
T4は、口座からのカウント(*)を選択する場合、ID = 3、
出力0;    
T5 ROLLBACK;    
存在するレコードを選択し、レコードへの挿入のための準備はありませんが、挿入を実行した場合、レコードがすでに存在しているが見つかりました。これを挿入することができないという問題点があります。

多くの人が両方と少し似実際、反復不能読み取りとファントム読み取りを混同する傾向があります。しかし、非反復は、更新、削除に焦点を読み取り、ファントムは焦点がインサートである読み込みます。

注意:非反復リードとファントムは差読み出される:前者は(変更または削除)を変更するために送信されたリードデータトランザクションを指し、後者は、トランザクションに提出された他の新しいデータを読み出すことをいいます。
この問題を解決するために、これらの2つの異なるアプローチのために、変更データを読み出す避け、変更のみでデータ操作を防止するために、行レベル・ロックの操作のためにデータを追加し、新しいデータを読み出す避け、多くの場合、テーブルレベルのロックを追加する必要があります新しいデータ(方法の複数のバージョンを使用してOracleデータを)防ぐために、テーブル全体ロック。

分離レベルは、ファントム読み取りの問題を避けて、トランザクションシリアル実行直列力になるように設定されている場合、以前と述べました。 

公開された900元の記事 ウォンの賞賛387 ビュー279万+

おすすめ

転載: blog.csdn.net/kingmax54212008/article/details/103839956