« 最近突然パスワードのオートコンプリートが使えるサイトが増えた | トップページ | Explainによるコストを取得するPL/pgSQL »

2014.08.30

Dirty Readは許容されない

トランザクションの分離レベル、というのはDBMSでトランザクション制御を習ったときに誰しもが学ぶ内容であろう。
その中で厄介者のごとく説明されるのが「ダーティリード」や「ファントムリード」である。
しかし、ダーティリードも時には便利なことがある。
例えば巨大なINSERT処理をしているときに、何件処理が進んだかを調べるときに、ダーティリードにてSELECT count(*) FROM insert_table;などをすると、countの進み具合で進捗がわかる、みたいな小技があり、Informixでは良く使っていた(^^;

で、同じことをPostgreSQLでも実行しようと思いトランザクションの分離レベルを変更しようとした。

PostgreSQLでは定義上、分離レベルは4つある。
-Read Uncommitted; これがDirty Readが発生しうる条件
-Read Committed; Defaultレベル。Dirty Readは発生しないがPhantom Readはある。
-Repeatable Read;
-Serializable;
そして分離レベルの変更は、またも登場SETで行なう。

SET TRANSACTION ISOLATION LEVEL xxxx;
xxxxに分離レベルを入れる。
じゃあ早速
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
分離レベルについてはSHOWで調べられるので、調べてみよう。
SHOW TRANSACTION ISOLATION LEVEL;
……結果は"Read Unommitted"。
よし、これで戦える!

そして喜び勇んでcountしてみたんだが、一向に思った結果が出てこない。
「なんだろう、なにがおかしいんだろう??」
と悩んだところでマニュアルを見る。


PostgreSQLでは、4つの標準トランザクション分離レベルを全て要求することができます。しかし、内部的には、リードコミッティド、リピータブルリードおよびシリアライザブルに対応する3つの独立した分離レベルのみがあります。リードアンコミッティドレベルを選択した時、実際にはリードコミッティドになり、リピータブルリードのPostgreSQLでの実装ではファントムリードの可能性はありません。このように実際の分離レベルは選択したレベルより厳密になることがあります。
と、いうことで、見た目上はRead Uncommittedを許容するのに、実際にはRead Committedのレベルになってしまう、という罠があるのである。

まあダーティリードをわざわざしたい、というケースはそう多くないだろうから、この仕様で困る人は多くないだろうとは思うけどね(^^;

|

« 最近突然パスワードのオートコンプリートが使えるサイトが増えた | トップページ | Explainによるコストを取得するPL/pgSQL »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/2022/60232508

この記事へのトラックバック一覧です: Dirty Readは許容されない:

« 最近突然パスワードのオートコンプリートが使えるサイトが増えた | トップページ | Explainによるコストを取得するPL/pgSQL »