トランザクション分離レベル
トランザクションの同時実行制御と分離性
トランザクションの同時実行制御と分離性は、データベースによって異なる。
Oracle : 一時領域を使用した「多バージョン法」
読み取るデータが更新中であっても検索処理が待たされることはない。
SQL Server : 「ロック法」
ロック法による同時実行制御のため、検索時に共有ロックをかける。 読み取るデータが更新中の場合は、すでにそのデータに排他ロックがかかっているため、共有ロックをかけることができない。
更新中のデータに読み手はアクセスできず、検索処理が待たされる。
Oracle
- トランザクション分離レベルのうち、Read Committed・Serializableをサポートしている。
SQL Server
トランザクション分離レベルのうち、Uncommitted Read・Read Committed・Repeatable Read・Serializableをサポートしている。
デフォルトはOracleと同じくRead Committedであるが、実際はREAD_COMMITTED_SNAPSHOT データベースオプションの設定によって動作が異なる。
READ_COMMITTED_SNAPSHOT データベースオプションがOFFの場合は、更新トランザクション中のSELECTはロック待ちとなる。
READ_COMMITTED_SNAPSHOT データベースオプションがONの場合は、通常のRead Committedの動作(多バージョン法)となる。
【参考】
Uncommitted Read
Dirty read・Fuzzy read・Phantom readが発生する。
Read Committed
Fuzzy read・Phantom readが発生する。
Repeatable Read
Phantom readが発生する。
Serializable
トランザクションの同時実行における3つの問題がどれも発生しない。 パフォーマンスを犠牲にして、ロックを行う方式。
【参考】トランザクションの同時実行における3つの問題
Dirty read
まだコミットされていない更新データをSELECT時に取得できてしまう。
Fuzzy read
あるトランザクションの中で別トランザクションによる更新のコミットがあった場合に、 別トランザクションによるコミットの前後でSELECTした場合、異なるデータが取得できてしまう。
Phantom read
あるトランザクションの中で別トランザクションによる更新のコミットがあった場合に、 別のトランザクションがその問い合わせ条件を満たす行を追加した場合、 別トランザクションによるコミットの前後でSELECTする、取得するレコード数も異なる。
参考
「DBMSのロック・分離戦略と同時実行制御」
http://techinfoofmicrosofttech.osscons.jp/index.php?DBMSのロック・分離戦略と同時実行制御#pc81bc15
DBの「トランザクション分離レベル」が必要な理由 (PostgreSQLで,ファントム・リードを防止すべきサンプル事例)
http://language-and-engineering.hatenablog.jp/entry/20110104/p1