学んだことのメモ帳ですこの広告は、90日以上更新していないブログに表示しています。2014-02-12MySQLでトランザクションの4つの分離レベルを試すトランザクションとは1つの作業単位として扱われるSQLクエリの集まりです。複数のUPDATEやINSERTをひとつの集まりとして、それらのクエリがすべて適用できた場合のみデータベースに反映します。ひとつでも適用に失敗したクエリがあった場合は、そのまとまりすべてのクエリの結果は反映しません。ACID特性トランザクション処理に求められる4つの特性です。(Atomicity)トランザクションに含まれる手順が「すべて実行されるか」「すべてされないか」のどちらかになる性質。(Consistency)どんな状況でもトランザクション前後でデータの整合性が矛盾なく保たれる性質。(Isolation)トランザクション実行中は、処理途中のデータは外部から隠蔽されて他の処理に影響を与えない性質。(Durability)トランザクションが完了したら、システムがクラッシュしてもデータが消失することがない性質。分離レベルMySQLに限らずSQL規格に則したデータベースでは4つの分離レベルを定義していて、トランザクションの内外で見える変更と見えない変更のレベルを設定できます。一般的に分離レベルが低いほど処理の並行性が高くなり処理速度向上が期待できますが、その分データの不整合などのリスクが発生します。UNCOMMITTED一番低い分離レベルです。コミットされていないトランザクションの結果が他のトランザクションから見える設定です。パフォーマンスが優れているわけではないので、使用されることは滅多にないそうです。コミット前のデータを読み取ることはダーティリードと呼ばれています。上図では、トランザクション1が商品の売上をINSERT処理している途中で、トランザクション2で商品価格を800円に変更をしています。値が戻る可能性もある非常に不安定な値となっています。Server)でデフォルトの分離レベルになっています。この分離レベルで見える値は、このトランザクションが開始されたときに既にコミットされている値だけで、このトランザクション内の値もコミットするまで他からは見えない状態になっています。UNCOMMITTEDで発生していたダーティリードは発生しません。トランザクション2の値がコミットされるまでは、変更前の値を参照しつづけます。COMMITTEDでは、次のような順番でSQLが発行された場合この状況が発生する可能性があります。トランザクション1のSQL:1で取得される商品番号111の価格は400円ですが、SQL:3で取得される商品の価格は800円になります。このようにトランザクション1を実行中にトランザクション2の処理が完了してしまい、トランザクション内で同じ値を参照しているのに数値が変わる現象をファジーリード(またはノンリピータブルリード)と呼びます。同じ問い合わせを2回繰り返しても、同じ結果になるとは保証できないということです。READMySQLのデフォルトの分離レベルです。READをデフォルトにしているのかわからないので、どなたか詳しい人教えて下さい。この分離レベルはトランザクション内が読み取る値が、そのトランザクション内では同じに見える事が保障されます。COMMITTEDで発生していたファジーリードは発生しません。トランザクション1で参照される価格の値は、トランザクション1が開始された時点の価格を参照し続けるので何度問い合わせをしても同じ値となります。READもある条件によっては問題が発生する可能性があります。トランザクション1は今までと同じように売上げた商品をテーブルにINSERTしています。その途中で、今日1日の売上価格を計算しているトランザクション2の処理が開始されます。トランザクション2のSQL:Aでは対象の売上件数は10件で価格の合計計算を行います。その後にトランザクション1の処理が完了し変更がコミットされ、トランザクション2のSQL:BでCOUNTをするとレコード数は11件となり、ひとつのトランザクション内で対象レコード数が異なってしまいます。トランザクション中に幻影のように新しい行が現れる事から、ファントムリードと呼ばれています。Control)という仕組みでファントムリードを防いでいます。ここはまだいまいち理解できてないので、後ほど調べます。SERIALIZABLE最も高い分離レベルです。複数トランザクションのSQLが入り混じらないように、強制的にトランザクションを順序付けて処理します。今まで出てきたすべての問題は発生しませんが、この分離レベルは読み取るすべての行にロックをかけます。ロック競合が多発することになるのであまりこのレベルが使用されることはありません。sec)ストレージエンジン確認トランザクションを利用できるInnoDBになっているか。READになっています。UNCOMMITTEDで確認します。※端末を2つ立ち上げます。COMMITTEDで確認します。※うまく分離レベルを変更できない事があったのでmysql端末を立ち上げなおして下さい。COMMITTEDで確認します。