[データベース] MySQLのInnoDBにおけるトランザクションの分離レベルと行ロックの基本:INSERTの挙動

SQLの構文

SQLの以下の構文で、トランザクションの分離レベル(ロックする度合い)をトランザクション単位で指定できる。

SET [SESSION | GLOBAL]
	TRANSACTION ISOLATION LEVEL
	{READ UNCOMMITTED | READ COMMITTED
	| REPEATABLE READ | SERIALIZABLE}

SESSION

現在の接続(セッション)のみに適用

GLOBAL

それ以降のすべての新規接続(セッション)に適用

分離レベルによる動作の違い

MySQLのInnoDBでは、分離レベルによって各種操作の動作が変わってくる。

基本、別セッションのINSERTを認めるか否かが大きな違い。

READ UNCOMMITTED

ロックなし。

READ COMMITTED

行ロックは行われるが、他のセッションにおけるINSERTは可能。

《行ロックする》
SELECT … FOR UPDATE
SELECT … LOCK IN SHARE MODE
UPDATE
DELETE

《行ロックしない》
SELECT

* 本来、標準のSQLではこのREAD COMMITTEDがデフォルト。

REPEATABLE READ

InnoDBでのデフォルト。

行ロックを行い、他のセッションにおけるINSERTをブロック。

《行ロックする》
SELECT … FOR UPDATE
SELECT … LOCK IN SHARE MODE
UPDATE
DELETE

《行ロックしない》
SELECT

SERIALIZABLE

REPEATABLE READとほぼ同等だが、単純なSELECTを自動的にSELECT … LOCK IN SHARE MODEに置き換えてロック。

行ロックを行い、他のセッションにおけるINSERTをブロック。

《行ロックする》
SELECT
SELECT … FOR UPDATE
SELECT … LOCK IN SHARE MODE
UPDATE
DELETE

まとめ

ややこしいが、行ロックするときは基本的にINSERTをブロックしたい場合が多いはずなので、デフォルトのREPEATABLE READのままでいいだろう。

データベースMySQL

Posted by takasho