都内で働くSEの技術的なひとりごと / Technical soliloquy of System Engineer working in Tokyo

都内でサラリーマンやってます。SQL Server を中心とした (2023年からは Azure も。) マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。英語の勉強のため、英語の

行ロックの動作についてお試ししてみる

 行単位にロックを獲得するため、下記のようなクエリを発行することがあるかと思います。

SELECT
    *  
FROM 
    WideWorldImporters.Sales.OrderLines WITH(XLOCK,ROWLOCK)
WHERE 
    OrderID = 10

 それでは下記のクエリをSQL Server Management Studio で実行してみましょう。

BEGIN TRAN
SELECT
    *  
FROM 
    WideWorldImporters.Sales.OrderLines WITH(XLOCK,ROWLOCK)
WHERE 
    OrderID = 10
COMMIT TRAN

f:id:koogucc11:20160828160551p:plain

 実際にどのようなロックがかかっているかチェックしてみましょう。下記のクエリを SQL Server Management Studio で実行してみましょう。

SELECT
    *
FROM
    sys.dm_tran_locks
WHERE 
    request_session_id = 55

 行ロックがかかっているのが判断できます。
f:id:koogucc11:20160828160735p:plain

 新しいクエリペインを開いて、下記のクエリを SQL Server Management Studio で実行します。またされてしまいますね。

SELECT
    *  
FROM 
    WideWorldImporters.Sales.OrderLines WITH(XLOCK,ROWLOCK)
WHERE 
    OrderID = 10

 新しいクエリペインを開いて、下記のクエリを SQL Server Management Studio で実行します。ロック要求がタイムアウトします。

SELECT
    *  
FROM 
    WideWorldImporters.Sales.OrderLines WITH(XLOCK,ROWLOCK,NOWAIT)
WHERE 
    OrderID = 10

f:id:koogucc11:20160828161144p:plain

NOWAIT オプションによって、ロック要求が即座にタイムアウトします。同じような動作は下記のクエリでも実現できます。

SET LOCK_TIMEOUT 0
SELECT
    *  
FROM 
    WideWorldImporters.Sales.OrderLines WITH(XLOCK,ROWLOCK)
WHERE 
    OrderID = 10

f:id:koogucc11:20160828161756p:plain

 業務仕様上許されるのであれば、NOWAIT の対応ができますね。無駄な待ちを発生させず、アプリケーションのパフォーマンスも向上するかと思います。

 プロとなるには、まだまだほど遠い....

プロとしてのSQLチューニング入門

プロとしてのSQLチューニング入門