30 Mar 2014, 00:43

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

データベーススペシャリストの勉強をしています。そのなかでよく出てくる「隔離性水準」について調べて見ました。 データベースにはトランザクションが持つべき特性であるACID特性というものを備えています。

ACID特性とは一般に下記の4つの特性のことを指しています。

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

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

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

1. ダーティリード

[概要]

あるトランザクションの処理中に、別のユーザがそのトランザクションでまだコミットしてないデータを読み込んでしまう現象のことです。
何が問題かというと、例えばそのトランザクションがロールバックしたとすると、存在しない処理のデータを読み込んでいることになってしまうことが発生してしまいます。

[対策]

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

2. ノンリピータブルリード

[概要]

同一トランザクション内で、一度読み込んだデータを再読み込みすると値が異なる現象です。

[対策]

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

3. ファントムリード

[概要]

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

[対策]

検索結果の範囲に対してロックをかけることです。
上記現象が起こらないようにトランザクションの分離レベルが用意されています。

トランザクションの分離レベルと、現象に発生の有無
分離レベル ダーティリード ノンリピータブルリード ファントムリード
Read Uncommitted あり あり あり
Read Committed なし あり あり
Repeatable Read なし なし あり
Serializable なし なし なし

Serializableは最強か

ここでひとつ疑問が湧いてきました。 どの事象も発生しないというSerializableの設定をしてしまえば何も気にしなくていいのだろうか。

残念ながらそう簡単にはいかないのです。
上の「トランザクションの分離レベルと、現象に発生の有無」でいえば、下にいけばいくほど、処理負担が大きく実行スピードが遅くなります。 つまりは、トランザクションの分離レベルと実行スピードはトレードオフになるということです。
そのときの要件や特徴に合わせて分離レベルを選ばなければならないのが現実です。 ちなみに、MySQLのInnoDBではデフォルトはRepeatable Readが設定されています。
まずは標準設定のままでよいと思います。

関連する記事はこちら
  • 実装案を使って、DBのViewの使いどころを検討する (2016/03/16)
  • ER図作成ツール MySQL Workbench を使ってみる (2014/05/06)
  • 【SQL テーブル結合】INNER JOIN とWHERE結合の違いについて (2014/02/28)
  • comments powered by Disqus
    このエントリーをはてなブックマークに追加