SQL Serverでは、複数のトランザクションが同時に実行される際の整合性を保つために「分離レベル」が設定されています。特に、READ_COMMITTED_SNAPSHOT はロック競合の回避に非常に有効で、実際に運用現場でも効果を発揮しています
🧱 分離レベルの種類と特徴
| 分離レベル | 特徴 | 発生する可能性のある問題 |
|---|---|---|
| READ UNCOMMITTED | ロックなし。最も緩い | ダーティリード、ファジーリード、ファントムリード |
| READ COMMITTED | コミット済みのみ読み取り | ファジーリード、ファントムリード |
| REPEATABLE READ | 読み取った行にロック | ファントムリード |
| SERIALIZABLE | 範囲ロックで完全分離 | 問題なし。ただし同時実行性が低い |
🧪 スナップショット方式の分離レベル
- READ COMMITTED SNAPSHOT 読み取り時点のスナップショットを参照することで、ロックを使わずに整合性を保ちます。ロック待ちが発生しないため、同時実行性が高く、パフォーマンス向上に寄与します。イメージはREAD UNCOMMITTEDとREAD COMMITTEDの中間的な性質を持っています。
- SNAPSHOT トランザクション開始時点のスナップショットを参照。より厳密な整合性を保ちます。
🔄 分離レベルの比較
上で紹介した分離レベルを整理すると、
| 分離レベル | ロック使用 | 読み取り整合性 | 同時実行性 | 備考 |
|---|---|---|---|---|
| READ UNCOMMITTED | なし | 低(ダーティリードあり) | 高 | 最も緩い。未コミットデータも読める |
| READ COMMITTED | あり(共有ロック) | 中(ダーティリードなし) | 中 | デフォルト。ロック待ちが発生する |
| READ COMMITTED SNAPSHOT | なし(行バージョン) | 中(ダーティリードなし) | 高 | ロックなしで整合性を保つ。RCの代替 |
| REPEATABLE READ / SERIALIZABLE | あり(強いロック) | 高 | 低 | 同時実行性が犠牲になるが整合性は高い |
✅ 実運用での効果:ロックタイムアウトの解消
筆者が保守しているシステムでは、SQL Server 2017を使用しており、デフォルトの分離レベルは READ COMMITTED でした。オンライン操作とバッチ処理が同時に走るタイミングで、ロックタイムアウトと思われるエラーが頻発していました。
しかし、サーバー更新のタイミングで分離レベルを READ_COMMITTED_SNAPSHOT に変更したところ、ロックタイムアウトが一切発生しなくなりました。この変更により、ユーザー操作とバッチ処理がスムーズに並行実行できるようになり、システムの安定性が大幅に向上しました。
⚙️ 設定方法と確認
設定:
ALTER DATABASE <データベース名> SET READ_COMMITTED_SNAPSHOT ON確認:
DBCC USEROPTIONSSet Option のisolation levelに設定されている値がトランザクション分離レベルです。SQLServer 2017では,デフォルトはREAD_COMMITTEDになっています。

📌 注意点
- tempDBの使用量が増えるため、リソース管理が重要
- 更新・削除処理のパフォーマンスに影響する場合がある
- システムの特性に応じて、適切な分離レベルを選択することが重要
まとめ
ロック競合やタイムアウトに悩まされている場合、READ_COMMITTED_SNAPSHOT の導入は非常に有効な選択肢です。筆者の実体験からも、分離レベルの見直しがシステムの安定性とパフォーマンス向上に直結することがわかります。SQL Serverの分離レベルを正しく理解し、適切に設定することで、より快適な運用が可能になります。

コメント