以前、アプリケーションの不具合によりSQL Serverであるテーブルのレコードのロックを取得したままとなり、解放されない事象が発生してしまいました。
上記事象を解決するために、ロックを解放するための手順を調査したのでここにメモ代わりに記載しておきます。
これから説明するトランザクションのロックの解放について、SSMSを使用した別の方法も別途記事にしています。
こちらはGUI操作のみなので、気になる方はこちらもご確認いただければ嬉しいです。
mr-star.hatenablog.com
前提
以下のようなサンプルのテーブルをこれからの説明で使用します。
CREATE TABLE [dbo].[Table_1]( [column1] [int] NULL, [column2] [varchar](50) NULL ) ON [PRIMARY] GO
トランザクションロック解放方法
実際に実行しながら確認していこうと思います。
まずは、トランザクションを開始して値の更新を行い、コミットせずにロックの状態を作っておきます。
※「SET IMPLICIT_TRANSACTIONS ON」で暗黙的トランザクションが設定済みです。
そのあと別のSQLシートを開き、以下のSQLを実行することでロックの状況を把握できます。
ロックしているテーブル名が判明している場合は、「TABLENAME」にそのテーブル名を指定して実行します。
SELECT OBJECT_NAME( t2.object_id ) AS tableName ,resource_type AS type ,request_session_id AS sessionId FROM sys.dm_tran_locks t1 INNER JOIN sys.partitions t2 ON t1.resource_associated_entity_id = t2.hobt_id WHERE OBJECT_NAME( t2.object_id ) = 'TABLENAME'; ;
実際に今回実行した結果は以下の通りです。
ロックされている場合には、このように実行結果としてレコードが抽出されると思います。
注目すべきは、「sessionId」列です。これはUPDATE文を実行しているプロセスのセッションIDとなります。今回は、「63」ですね。これを次の手順で使うので控えておきます。
ロック状態を解放するためには、KILLコマンドを使います。
上記で判明した「sessionId」を引数にして以下のように実行することでそのセッションIDを持つプロセスを終了することができます。
KILL <sessionId>;
それでは、実行してみましょう。以下の通り、コマンドが成功すればOKです。
先ほどのロックの状態を確認するSQLを実行してみると、レコードが抽出されなくなりました。
これでロック解放ができている状態になります。
おわりに
いかがでしたでしょうか。万が一ロックの状態が残ってしまったりしたら、この手順で確認して解放することができます。
また、アプリケーションをデバッグ実行しながらロックの状態を確認したりする場合も使えるかと思いますので是非試してみてください。
今回も最後までお読みいただきありがとうございました。この辺で失礼いたします。