-
Notifications
You must be signed in to change notification settings - Fork 0
MS_SQLServerConnectionSession
- 戻る(SQL Server)(SQL Server のクエリ)
- SQL Server のコネクションとセッション
- SQL Server のトリガ / SQL Server のオプティマイザ
コネクションとセッション、そして、トランザクションとの関連。
- SQL Server の「コネクション」と「セッション」について at SE の雑記
http://blog.engineer-memo.com/2016/01/02/sql-server-%E3%81%AE%E3%80%8C%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%8D%E3%81%A8%E3%80%8C%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%8D%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/
-
クライアント、サーバー間の接続。
-
以下で意識する。
- コネクションのオーバーヘッド
- 消費リソース / コネクション
- コネクション・プーリング
- 通常は、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
- 複数のアクティブな結果セット
-
複数のバッチを単一の接続で実行できる機能。
-
本機能を使用すると、
-
1 コネクション:1 セッションのところが、
-
1 コネクション:n セッションになる。
-
サンプルコードを見ると、
- 1 コネクション中に複数の
DataReaderで使用するクエリの結果セットを
保持できるもよう。 - 若しくは、カーソル操作(読み取りと更新)を非同期に処理することができる。
- 1 コネクション中に複数の
-
機能を有効にするには、キーワード ペア
"MultipleActiveResultSets=True"を
接続文字列に追加。
-
移行メモ(正誤): 接続文字列のキーワードは
MultipleActiveResultSet(単数形)ではなく
**MultipleActiveResultSets(複数形)**が正しい。
補足(MARS を使うべきか): MARS は
「DataReaderを開いたまま同じ接続で別のコマンドを実行したい」
という要求を解決するが、以下の理由で安易な有効化は勧められない。
- 内部的にセッションが増え、リソース消費とロックの挙動が読みにくくなる
DataReaderを開いたままの更新は、意図しないロック競合を招きやすい- EF Core など一部のシナリオでは MARS が必要になるが、
それ以外は接続を分けるか、先に読み切ってから更新する設計で回避できるなお、MARS は「並列実行」ではない。
1 接続上でインターリーブされるだけで、同時に走るわけではない。
-
バインドされた接続(bind connections)などと呼ばれるが、超マイナーな機能。
-
2 つの接続を 1 つにまとめる事が出来る。
-
MARS の前身の機能で、本機能の登場により、
複数の結果セットを保持する目的では使用しなくなった。 -
トランザクションもまとめる事が出来る
(セッションをバインドすると、同じトランザクションに参加できる)。
-
-
参考
- Share a single transaction using sp_getbindtoken sp_bindsession
https://www.sqlindia.com/share-a-transaction-using-sp_getbindtoken-sp_bindsession/
- Share a single transaction using sp_getbindtoken sp_bindsession
補足(最新化):
sp_getbindtoken/sp_bindsessionによる
バインドされた接続は非推奨であり、新規開発では使用しない。
複数の接続で 1 つのトランザクションを共有したい場合は、
TransactionScope(→ MS-DTC)を使うか、
そもそも接続を 1 つに束ねる設計にする。
-
SQL Server
-
sp_getbindtoken (Transact-SQL)
https://learn.microsoft.com/ja-jp/sql/relational-databases/system-stored-procedures/sp-getbindtoken-transact-sql -
sp_bindsession (Transact-SQL)
https://learn.microsoft.com/ja-jp/sql/relational-databases/system-stored-procedures/sp-bindsession-transact-sql
-
- 複数のアクティブな結果セット (MARS)
https://learn.microsoft.com/ja-jp/sql/connect/ado-net/sql/multiple-active-result-sets-mars
- ADO.NETデータプロバイダ(コネクション・プーリング)
- ADO.NETデータプロバイダの接続文字列
- SQL Server でのロック・タイムアウト
Tags: 移行, データアクセス, SQL Server
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。