SQL Server Snapshot Isolation

TechEd 2008 NorthAmerica メモ

MSやPASSJのセミナーで何度か耳にしたのだが、SQL Server 2005 移行には Snapshot Isolation (スナップショット分離レベル)が実装されている。

Oracle での既定の動作と同じになるというところが売り文句だが、トランザクション開始時等のデータを保存するために tempdb を酷使するのでパフォーマンス的には不利なようだ。

ただし、Snapshot Isolation を利用した場合、このデータ保存 Row versioning を行っているおかげで、with(READPAST) ヒントを使いロックを回避して最後にコミットされた正しいデータを読みだすことができる。with(nolock) もロックを回避できるが、これはトランザクションの途中のデータかもしれず、正しいかどうかは分からない。

Serealizable Isolation のロックは Range Shared Lock となるが、これについては SQL Serverのロック管理 (.NETエンタープライズ Webアプリケーション開発技術大全) が分かりやすいので省略。なにより内部的な動作を知ったからといってチューニングの役に立つ場面が思い浮かばない。

ただし重要な点として、Range Shared Lock は「インデックスキー範囲ロック」であるので、インデックスが存在していない場合テーブルロックになってしまう。主キーを設定しないテーブルはそうは多くないと思うが、より確実に主キーおよびインデックスの付与を検討したい。

プログラミング上は、Serializable のように強力な分離レベルを利用した場合、ロックによるSQL文実行待機の発生機会が多くなる。長時間のタイムアウトまで待たせてOKなアプリケーションというのはそう多くはないと思われるので、SET LOCK_TIMEOUT を利用してタイムアウト時間を人間が待てる程度まで短くし、エラー処理を記述すべきである。

SET LOCK_TIMEOUT 0 に設定し、ロックされていたら即時にエラー処理に入るという戦略もあり。

ロックの監視にあたっては、sys.dm_tran_locks や sys.dm_exec_… あたりのDMVを活用する。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。