【SQL Server】ロックの粒度に気をつけよう

Programming

2021年12月29日

post-cover

ロックの粒度には気をつけよう

こんにちは。ここ最近業務でSQLのパフォーマンス改善を中心に取り組んでいました。
適切なロックの粒度が考慮されていないがためにデッドロックやロック取得待ちが頻繁に発生していました。

このような状況を防ぐためには、SQLを発行するシチュエーションを考慮して
適切な「トランザクション分離レベル」を設定する必要があります。

SQL Serverのトランザクション分離レベルについては公式ドキュメントを参照してください。
トランザクション分離レベル - SQL Server | Microsoft Docs


シチュエーション別のトランザクション分離レベル

実装する機能によって適切なトランザクション分離レベルは異なります。
以下に2つの例を示します。


①検索画面・・・READ UNCOMMITTED
検索画面の一覧系は基本的に__READ UNCOMMITTED__で問題ないでしょう。
トランザクション分離レベルをREAD UNCOMMITTEDに設定するとテーブルのロックを取得することがなくなるため、更新機能とのバッティングが発生しなくなります。


トランザクション単位で、トランザクション分離レベルを変更するには
クエリの最初に「SET TRANSACTION ISOLATION LEVEL」を指定する必要があります。

sql
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
-- 以下、クエリを記載


ただし、正確な数字を表示する必要がある場合はREAD COMMITTEDが適切となります。
プログラムの設計を考慮したうえで適切なトランザクション分離レベルを設定してください。

②データ登録画面(更新系)・・・READ COMMITTED
データを更新する機能の場合は READ COMMITTED が適切でしょう。

READ UNCOMMITTEDやREPEATABLE READの場合、ダーティリードやロストアップデートの影響で想定外のUPDATEやINSERTが行われる可能性があります。


sql
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
-- 以下、クエリを記載

適切なトランザクション分離レベルを意識しよう

以上、ロックの粒度について「トランザクション分離レベル」に触れて記載しました。
クエリで無駄なロック取得待ちを発生させないために、常に意識できるようにしていきたいですね。

© 2025 Dev tak Diary