データベース: トランザクション分離レベルについてまとめてみる

BPSでは社内でデータベーススペシャリスト試験の勉強会をしています。
その中でトランザクション分離レベルについての問題を議論したので、その内容を書きたいと思います。

ダーティ
リード
ノンリピータブル
リード
ファントム
リード
対策例
READ UNCOMMITTED 発生する 発生する 発生する
READ COMMITTED 発生する 発生する ダーティリードを防ぐため更新時には対象の行に専有ロックを行う
REPEATABLE READ 発生する ノンリピータブルリードを防ぐため参照時に対象の行に共有ロックを行う
SERIALIZABLE ファントムリードを防ぐため参照時に対象のテーブルに共有ロックを行う

1. ダーティーリード

ダーティリードはトランザクション処理において、あるトランザクションが更新されている最中に、他のトランザクションからデータを読み出すことができてしまう現象のこと。

ここではトラン2が”りんご”を”みかん”に変更した後、トラン1が”みかん”を読み込むがその後、トラン2によって”みかん”は”りんご”にロールバックされます。
汚れ(誤り)のあるデータを読み込んでいることがわかります。

図の例の場合の対策例としてはトランザクション2が専有ロック(他のトランザクションによる書き込み、読み込み不可)を対象の行にかける等が考えられます。

2. ノンリピータブルリード(ファジーリード)

読み出した行がほかのトランザクションにより更新または削除され、同じトランザクションで再度同じ行を読み込んだときに、その行が更新または削除されていること。

ここではトラン1が”りんご”を読み出した後、トラン2により”りんご”が”みかん”に更新され、トラン1が同じ再度、読み込みをした際に”みかん”を読み込んでしまいます。

図の例の場合の対策例としては、トランザクション1で共有ロック(他のトランザクションによる読出し可、更新不可)をかける等が考えられます。

3. ファントムリード

ある探索条件を満たす行の集合を読み込んだ後、ほかのトランザクションによる行の挿入または更新により、その探索条件を満たす行が生成され、再度同じ探索条件を読み込んだときに、異なる行の挿入が得られる。

ここではトラン1で果物の集合として”りんご”、”みかん”の2行を読出ししますが、その後、トラン2により新たに果物として”バナナ”が追加されたことにより、再度、トラン1で果物集合を読み込んだ際に”バナナ”を加えた3行が読出しされてしまいます。

図の例の場合の対策例としては、トランザクション1でテーブルに対して共有ロック(他のトランザクションによる読出し可、更新不可)をかける等が考えられます。

実際のDBスペシャリスト試験の問題例

こちらの問題は上記の概念を使ったものになっています。
ぜひチャレンジしてみてください。

参考文献

下記の記事を見るとDBMSごとにトランザクションの分離レベルの実装はかなり違うことがわかります。

データベーススペシャリスト合格教本 山平耕作著 技術評論社

関連記事

Rails: ループ内の手続処理を止めてみよう

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ