Skip to content

MS_SQLServerConnectionSession

nishi_74322014 edited this page Aug 13, 2026 · 1 revision

SQL Server のコネクションとセッション

概要

コネクションとセッション、そして、トランザクションとの関連。

詳細

コネクション

  • クライアント、サーバー間の接続。

  • 以下で意識する。

    • コネクションのオーバーヘッド
    • 消費リソース / コネクション
    • コネクション・プーリング

セッション

  • 通常は、1 コネクション・1 セッション。
  • MARS を使用すると、1 コネクション・n セッションになる。

補足(用語の階層と対応する DMV): SQL Server 側では
以下の 3 層で管理されており、それぞれ対応する DMV がある。

内容 DMV
接続(connection) TCP / Named Pipes 等の物理的な接続 sys.dm_exec_connections
セッション(session) ログインの単位。SET オプションや分離レベルを保持 sys.dm_exec_sessions
要求(request) 実行中の 1 つのバッチ/クエリ sys.dm_exec_requests

session_id(SPID)で 3 つを結合して調べるのが基本形。

SELECT
    s.session_id, s.login_name, s.host_name, s.program_name,
    s.status, s.transaction_isolation_level,
    c.client_net_address, c.num_reads, c.num_writes,
    r.blocking_session_id, r.wait_type, r.wait_time,
    t.text AS sql_text
FROM sys.dm_exec_sessions AS s
LEFT JOIN sys.dm_exec_connections AS c
       ON s.session_id = c.session_id
LEFT JOIN sys.dm_exec_requests AS r
       ON s.session_id = r.session_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) AS t
WHERE s.is_user_process = 1
ORDER BY s.session_id;

program_name は、接続文字列の Application Name
ADO.NETデータプロバイダの接続文字列)が入るため、
アプリ側で必ず設定しておくと障害解析が格段に楽になる。

補足(セッションはトランザクションの器): トランザクションは
セッションに属する。このため、

  • 接続プールから取得した接続に、
    前の利用者のトランザクションが残っていることはない
    Dispose 時に未コミットのトランザクションはロールバックされる)
  • ただし SET オプション(ARITHABORT など)は
    sp_reset_connection でリセットされるものと、されないものがある
  • 「開発では速いのに本番で遅い」の典型的な原因の 1 つが、
    SSMS と アプリで ARITHABORT の既定値が異なることによる
    実行プランのキャッシュ分岐である

ロック待ちやデッドロックとの関係は
SQL Server でのロック・タイムアウトを参照。

MARS (Multiple Active Result Sets)

  • 呼称

    • MARS : Multiple Active Result Sets
    • 複数のアクティブな結果セット
  • 複数のバッチを単一の接続で実行できる機能。

    • 本機能を使用すると、

    • 1 コネクション:1 セッションのところが、

    • 1 コネクション:n セッションになる。

    • サンプルコードを見ると、

      • 1 コネクション中に複数の DataReader で使用するクエリの結果セットを
        保持できるもよう。
      • 若しくは、カーソル操作(読み取りと更新)を非同期に処理することができる。
    • 機能を有効にするには、キーワード ペア "MultipleActiveResultSets=True"
      接続文字列に追加。

移行メモ(正誤): 接続文字列のキーワードは
MultipleActiveResultSet(単数形)ではなく
**MultipleActiveResultSets(複数形)**が正しい。

補足(MARS を使うべきか): MARS は
DataReader を開いたまま同じ接続で別のコマンドを実行したい」
という要求を解決するが、以下の理由で安易な有効化は勧められない

  • 内部的にセッションが増え、リソース消費とロックの挙動が読みにくくなる
  • DataReader を開いたままの更新は、意図しないロック競合を招きやすい
  • EF Core など一部のシナリオでは MARS が必要になるが、
    それ以外は接続を分けるか、先に読み切ってから更新する設計で回避できる

なお、MARS は「並列実行」ではない。
1 接続上でインターリーブされるだけで、同時に走るわけではない。

sp_getbindtoken / sp_bindsession

  • バインドされた接続(bind connections)などと呼ばれるが、超マイナーな機能。

  • 2 つの接続を 1 つにまとめる事が出来る。

    • MARS の前身の機能で、本機能の登場により、
      複数の結果セットを保持する目的では使用しなくなった。

    • トランザクションもまとめる事が出来る
      (セッションをバインドすると、同じトランザクションに参加できる)。

  • 参考

補足(最新化): sp_getbindtoken / sp_bindsession による
バインドされた接続は非推奨であり、新規開発では使用しない。
複数の接続で 1 つのトランザクションを共有したい場合は、
TransactionScope(→ MS-DTC)を使うか、
そもそも接続を 1 つに束ねる設計にする。

参考

Microsoft Learn

sp_getbindtoken / sp_bindsession

MARS (Multiple Active Result Sets)

関連


Tags: 移行, データアクセス, SQL Server

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally