分離レベルについて説明する
トランザクション
分離レベルを理解するには、まずトランザクションを理解する必要があります。 MySQL では、次の 2 種類のトランザクションがサポートされています。
- オートコミット。 各 SQL ステートメントはトランザクションであり、変更はすぐにコミットされます。 サーバー パラメーターはオートコミットであり、既定では ON に設定されています。
-
明示。 明示では、トランザクションが
START TRANSACTION
またはBEGIN
というキー ワードで始まり、COMMIT
またはROLLBACK
というキー ワードで終わる必要があります。 明示的なトランザクションを使用すると、ステートメントのグループを一緒にコミットするか、一緒にロールバックすることができます。 部分的にコミットしたり、部分的にロールバックしたりすることはできません。
競合
多くのクライアントが同じデータベースに接続されている場合、同じデータを変更して読み取ろうとする可能性が高くなります。 複数のユーザーが同時にデータを変更しようとすると、次のような問題が発生します。
- ダーティ リード - あるユーザーが、別のユーザーによって更新処理中のデータを読み取る場合。 最初のユーザーはデータを読み取り、2 番目のユーザーは変更をディスクにコミットしてデータを更新します。 最初のユーザーは最新ではない情報を取得することになります。
- 更新データの喪失 - あるユーザーが一部のデータを更新し、その変更が別のユーザーによって上書きされること。 最初のユーザーのデータは喪失します。
-
反復不能読み取り - 2 人のユーザーが同じクエリを使用してデータベースにクエリを実行したが、別のユーザーがデータを更新したために異なる情報を受け取る場合。 元のユーザーによって作成された
SELECT
ステートメントは、実行時に異なるデータを返すので、反復不能です。 - ファントム読み取り - トランザクションの進行中に行が追加または削除されるときに発生します。 同じクエリが再度実行されると、異なる行数が返されます。
分離レベル
これらの問題は、ストレージ エンジン レベルまたはセッションの分離レベルを設定することによって管理されます。 4 つの分離レベルは次のとおりです。
- READ UNCOMMITTED - データにロックは設定されません。つまり、"ダーティ リード" が可能です。 あるユーザーは、他のユーザーによって変更されているデータを読み取ることができますが、変更されたデータはまだディスクにコミットされていません。
- READ COMMITTED - コミットされていない変更を他のユーザーに表示しないようにすることで、ダーティ リードを防止します。 各 SELECT ステートメントで使用できるのは、コミットされたデータだけです。 READ COMMITTED では、同じトランザクション内で複数のクエリが実行されている場合でも、反復不能読み取りが発生する可能性があります。 この状況は、2 人のユーザーが同じデータを選択しても、異なる結果を得ることができることを意味します。 READ COMMITTED は、SQL Server や PostgreSQL など、他の一般的なリレーショナル データベースにおける既定の分離です。 MySQL の既定値ではありません。
-
REPEATABLE READ - これは InnoDB ストレージ エンジンの既定のトランザクション分離レベルです。 データのスナップショットを作成し、同じ
SELECT
が実行された時にそれを使用する事で、同じトランザクション内で一貫性のある読み取りを保証します。 これにより、反復不能読み取りの問題が解決されますが、パフォーマンスに影響を与える可能性があります。 - SERIALIZABLE - これは最も制限された分離レベルです。 これにより、すべての行にロックが設定され、1 つのトランザクションが別のトランザクションに干渉することは許可されません。 1 つのトランザクションによって選択された行は、トランザクションが完了するまで、他のユーザーが変更することはできません。 SERIALIZABLE は、データ読み取りが常に一貫していることを保証します。
サーバー パラメーターの既定の分離レベルを表示または修正できます。 transaction_isolation は、既定の分離レベルを定義するパラメーターです。