ITエンジニアの成長ブログ

ITエンジニアとして行う勉強の発信&日々の生活で体験した楽しいことをゆるく発信

SQL Serverでトランザクションのロックを解放する方法

以前、アプリケーションの不具合により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を実行してみると、レコードが抽出されなくなりました。
これでロック解放ができている状態になります。

トランザクションロック解放方法④

おわりに

いかがでしたでしょうか。万が一ロックの状態が残ってしまったりしたら、この手順で確認して解放することができます。
また、アプリケーションをデバッグ実行しながらロックの状態を確認したりする場合も使えるかと思いますので是非試してみてください。

今回も最後までお読みいただきありがとうございました。この辺で失礼いたします。