読者です 読者をやめる 読者になる 読者になる

Goldstine研究所

mosuke5's tech blog

ブログ移転しました。5秒後にリダイレクトします。

データベース、隔離性水準とはなにか

データベースには、トランザクションが持つべき特性であるACID特性というものを備えている。
ACID特性

A Atomicity 原始性
C Consistency 一貫性
I Isolation 隔離性
D Dirability 耐久性

ACID特性については詳しく書かないが、その中に隔離性という以下の特性がある。
複数のトランザクションを並行して実行しても直列に実行した時と同じ結果になる。
また、トランザクション実行中は変更前の状態として見える。

しかし、複数のトランザクションを並列で実行すると、その隔離性を満たさない現象が発生することがある。
その現象は主に3つある。

1. ダーティリード
[概要]
あるトランザクションの処理中に、別のユーザがそのトランザクションでまだコミットしてないデータを読み込んでしまう現象のこと。
Q. 何が問題なの?
A. 例えばそのトランザクションロールバックしたとすると、存在しない処理のデータを読み込んでいることになってしまう。

[対策]
対策はシンプルで、まだコミットしていないデータは読み込めないようにするだけ。
つまり、データを更新するときは「排他ロック」をかけるようにするということ。

2. ノンリピータブルリード
[概要]
同一トランザクション内で、一度読み込んだデータを再読み込みすると値が異なる現象。

[対策]
データを読み込むときには「共有ロック」をかけるようにするということ。
共有ロック中は他トランザクションから更新はできなくなるのでノンリピータブルリードは起きない。

3. ファントムリード
[概要]
あるトランザクションが複数行ある結果を返す検索条件で問合せを2度実行する間に、
コミットされた別のトランザクションによってその条件を満たす新しい行が挿入されたり、削除された行がでたりする現象。

[対策]
検索結果の範囲に対してロックをかけること。


上記現象が起こらないようにトランザクションの分離レベルが用意されている。

トランザクションの分離レベルと、現象に発生の有無

分離レベル ダーティリード ノンリピータブルリード ファントムリード
Read Uncommitted あり あり あり
Read Committed なし あり あり
Repeatable Read なし なし あり
Serializable なし なし なし

ここでひとつの疑問が…

Q. どの現象も起こらないSerializableに設定してしまえば…!?
当然だがそう簡単にはいかない。
上の「トランザクションの分離レベルと、現象に発生の有無」でいえば
したにいけばいくほど、処理負担が大きく実行スピードが遅くなります。

つまりは、トランザクションの分離レベルと実行スピードはトレードオフ
そのときそのときの特徴に合わせて分離レベルを選ばなければならない。

ちなみに、MySQLInnoDBではデフォルトはRepeatable Read。
まずは標準のままでよいと思います。