【MySQL】トランザクション独立性レベルおよびACID

5830 ワード

注意:beginまたはstart transactionは、トランザクションの開始点ではなく、実行後の最初の操作InnoDBテーブルの文で、トランザクションが本格的に開始されます.start transaction with consistent snapshotコマンドは、すぐにトランザクションを開始できます.
1、独立性レベル
1.1、基本概念
現在のトランザクションは、他のトランザクションがコミットしていない変更値に読み込むことができます.
現在のトランザクションは、他のトランザクションがコミットした変更値を読み込むことができます.
1つのトランザクションがいつでもクエリされた結果は、トランザクションが開始されるとクエリの結果と同じです.
すべてのトランザクションを連続的に実行します.
1.2、小テスト一
独立性レベルの基本概念を理解した後、小さなテストをして、本当に理解したかどうかを見てみましょう.次の2つのセッションは順番に実行され、最後に各独立性レベルのV 1、V 2の値はそれぞれいくらですか.
sessionA
sessionB
トランザクションの開始
クエリ取得値1
トランザクションの開始
値1を値2に更新
クエリ取得値V 1
トランザクションのコミット
クエリ取得値V 2
トランザクションのコミット
クエリ取得値V 3 は、他のトランザクションのコミットされていない値を読み取ることができるので、V 1はセッションBのコミットされていない変更を読み取り、値は2である. は他のトランザクションがコミットしていない値を読み取ることができないので、V 1の値は1であり、V 2をクエリするとセッションBがコミットされ、このときに読み込まれたV 2は2である. クエリで得られた値は、トランザクションの開始時の値であるため、V 1およびV 2の値はいずれも1である. でセッションAがトランザクションを開始すると、セッションBはセッションAのトランザクションのコミット後に実行されるまで詰まってしまうため、V 1とV 2はいずれも1であり、V 3クエリ時にセッションBがトランザクションをコミットしたため、V 3の値は2となる.
V1
V2
V3
読み取りコミットなし
2
2
2
リードコミット
1
2
2
リピート可能
1
1
2
シリアル化
1
1
2
1.3、小テスト二
上記の小さなテストでは、トランザクション・独立性レベルの理解が深まります.次に、繰り返し読み取り可能な独立性レベルで小さなテストを変更して理解を深めます.例は次のとおりです.
sessionA
sessionB
トランザクションの開始
クエリのV値は1
トランザクションの開始
set V=V+1
クエリ取得値V 1
トランザクションのコミット
set V=V+1
クエリ取得値V 2
トランザクションのコミット
クエリ取得値V 3
小テストの繰り返し読み取り可能独立性レベルにおけるV 1、V 2の値はいずれも1であり、V 3の値は2である.小テスト1の考え方から、小テスト2の結果はV 1が1、V 2が2となるかもしれませんが、V 3はいくらですか.実は正解はV 1が1、V 2が3、V 3が3です.sessionAのset V=V+1がset V=1+1であれば、sessionB更新の操作が失われ、データが正しくない場合、sessionBがコミットされているため、sessionAの更新は同じ値 でset V=2+1となるので、V 2は3となる.小テスト1で読み取ったデータは、概念的には である.プロセスでセッションBのコミットトランザクションをセッションAのコミットトランザクションの後ろに置くとしたら?このときsessionAのset V=V+1は、sessionBのトランザクションがコミットされるまでブロックされ、結果はV 1が1、V 2が3、V 3が3となる.
MySQLのトランザクション独立性レベルはデフォルトでは繰り返し読み取り可能であり、oracleのトランザクション独立性レベルはデフォルトでは読み取りコミットであるため、oracleをMySQLに移行する際にはMySQLの設定を読み取りコミットした後の操作を覚えておく必要があります. は、トランザクションの開始時にビューを作成し、その後のクエリがこのビューで動作します. は、トランザクションの開始時にビューを作成しますが、他のトランザクションの更新操作によって直接ビューが更新されます. は、データベース内の最新のデータを直接読み込みます. は、他のトランザクションの変更を回避するためにロックを直接行います.
view1
view2
1
2
上記の表に示すように、行データが1から2に更新されるプロセスは、ビューview 1からview 2へのプロセスに対応する.読み出しコミット独立性レベルでは、トランザクションが開始されるとview 1ビューとなり、sessionBがデータを更新するとビューview 1がビューview 2に更新され、その後のクエリがview 2で行われます.繰り返し読み取り可能独立性レベルでは、トランザクションが開始されるとview 1ビューになり、sessionBが更新されると、トランザクションはview 1ビューをそのまま読み込みます.繰り返し読み取り可能独立性レベルでは、view 1ビューをどのように見つけますか?実はこれがMVCCの機能で、トランザクションは起動時にシステムが順次増加するtransaction idを割り当てることを獲得して、それからトランザクションはデータを更新する時このtransaction idをこの行のデータに割り当ててtrx row_としますid、ついでにundo logログを記録します.たとえば、上のセッションAトランザクションが起動時に取得したtransaction idが889、セッションBのtransaction idが890の場合、セッションB更新後のデータのtrx row_idは890です.V 2の値を問い合わせると、sessionAはデータバージョンが890であり、現在の自己トランザクションidが889であることを発見したので、undo log「ロールバック」を利用して前のバージョンのデータを表示し、前のバージョンは889であっても889より小さいtrx row_であってもよいid、値を取ります.
1.4、隔離レベルで汚れた読み、重複しない読み、幻読みを解決する
宣言すると、読み取りがコミットされていない、読み取りがコミットされていない、繰り返し可能な、シリアル化された独立性レベルが順次増加し、独立性が厳しいほど効率が低下します.
トランザクションは、他のトランザクションの変更後にコミットされていない値に読み込まれます.
トランザクションが開始されたときに読み込まれた値は、トランザクションが実行中に再読み込みされた値とは異なります.
トランザクションが開始されると、他のトランザクションがデータベースに新しく挿入したローがこのトランザクションに読み込まれます.幻読みは、新しく挿入された行のみを指します.
上記の汚い読み、繰り返し不可読み、幻読みの概念と隔離レベルによって、私は以下の関係を得ることができます.
汚読
繰り返し不可
まぼろし読み
読み取りコミットなし
かもしれない
かもしれない
かもしれない
リードコミット
あり得ない
かもしれない
かもしれない
リピート可能
あり得ない
あり得ない
かもしれない
シリアル化
あり得ない
あり得ない
あり得ない
2、ACID A.Atomicity.
1つのトランザクションの操作は、すべて成功するか、すべて失敗します.例えばAはBに100元振り込んで、A口座が100元減ることを保証して、B口座は100元増加して、この100元はAが回転してきたので、A口座が減少したのに、B口座は100元増加することに対応していません.
原子性はundo logによって実現され,undo logはロールバック情報を記録し,トランザクションが失敗したりrollbackを行うと,情報に基づいて操作前の様子にロールバックする.deleteの場合、undo logは削除されたデータの情報を記録し、ロールバックが発生するとinsert操作を行う.updateの場合、undo logは更新操作の情報を記録し、ロールバックが発生するとupdate操作を行う.Insertの場合、undo logは対応するプライマリ・キーを記録し、ロールバックが発生した場合にdelete操作を行います.C.Consistency.
トランザクションは実行前後に、データが合法的な状態から別の合法的な状態に変わります.どのように合法と言えば、すべて自分で定義することができて、例えば事務が起動する時Aユーザーの口座は1000元で、Bユーザーは500元あって、この時は起動する時合法的な状態です.AユーザーはBユーザーに100元振り込み、Aユーザー口座残高は900、Bは600となり、これは終了時に合法的な状態である.あるいはプラットフォームは1%の手数料を差し引いて、振り替えが完了した後にAユーザーの残高は899で、Bユーザーは600になって、プラットフォームの口座は1元増加して、これも合法的な状態です.
一致性は原子性、隔離性、持続性によって保証される.だからAID特性を保証してこそ、C特性を保証することができる.I.Isolation.
1つのトランザクションのクエリー結果は、他のトランザクションに影響されず、トランザクション間は隔離されています.たとえば、Xトランザクションが起動時にid=1をクエリーした結果が1であり、Xトランザクションがこのレコードを変更しなかった場合、他のトランザクションがこのレコードを変更したかどうかにかかわらず、複数回クエリーした結果が1である.
独立性はMVCCによって実現され,具体的な実装は上記の小さなテストロジックを参照することができる.D.Durability.
トランザクションの実行が完了すると、変更したデータをデータベースに保存できます.ダウンタイムや突然の電源オフにかかわらず、データベースの再起動後にクエリーされたデータはトランザクション操作後のデータです.
持続性はredo logによって実現され、MySQLにはWALの論理があり、データを編集するときにredo logログを更新し、メモリを更新し、最後にディスクを書く.redo logログを書くのは非常に速い操作ですが、メモリを更新した後、ディスクに書くのは忙しいです.ディスクに書き込んでいないときにダウンタイムが発生するなど、MySQLが再起動すると自動的にredo logログとディスクの内容を比較し、ディスクに書き込んでいないデータをディスクに書き込んで、データの持続性を保証します.
3、知識を広げるundo log
ロールバック・ログ・レコードデータ変更の逆リストア・オペレーション・レコード.例えば、データ値は1から順に2、3、4に変更される.ロールバックログは、2->1、3->2、4->3の順に記録されます.MVCC
Multi-Version Concurrency ControlはMySQLデータベースのマルチバージョン同時制御であり、同じレコードがデータベースに複数のバージョンが存在することができる.undo logと楽観的なロックによって実現される.
衝突しないと楽観的に考えて、最後にデータを修正する必要があるときにロック認証を取っておけばいいです.一般的な方法は、バージョン番号制御とタイムスタンプ制御です.
悲観的には、データは他のトランザクションによって変更されると考えられているので、データを取得するときに直接鍵をかけ、他のトランザクションの変更を阻止します.例えばfor update.