web-dev-qa-db-ja.com

SQL Server-発生する可能性のあるタイムアウトのタイプとその方法

SQL Serverを使用する場合、それにアクセスする複数のアプリケーションホストがあり、各アプリケーションは1つまたは複数の接続を持つことができます。各接続には複数のトランザクションが含まれる可能性があります(間違っている場合は修正してください)。各トランザクションは、クエリSQLまたは非クエリSQLを実行できます。

私の経験では、排他的にロックされているテーブルをクエリすると、簡単にタイムアウトになりました。また、2つの異なるアプリケーションが同じリソースをロックすると、SQL Serverがタイムアウトではなくデッドロック例外を検出してスローすることも確認しました。また、インデックスタイムアウトの再構築も示しています。これは、誰かがまだテーブルに接続していることが原因である可能性があります。

ただし、SQL Serverがそれを検出しない、またはタイムアウトになるという一種のデッドロックも発生します。このアプリケーションでは、2つの接続、2つの個別のトランザクションを開きました。最初のトランザクションはリソースをロックし、2番目のトランザクションは同じリソースにアクセスしようとしましたが、最初のトランザクションは閉じていません。

誰かがタイムアウトやデッドロックのタイプのリストを提供するとしたら、アプリケーションで作業するときにこの種のケースを回避するのに役立ちます。

8
dsum

アプリケーションの観点からは、次のものがあります。

  • 接続タイムアウト(アプリがSQL Serverへの接続を確立するために待機する時間)
  • コマンドタイムアウト(アプリがコマンドの完了を待機する時間(SQL Serverからの結果のプルダウンを含む))

私のクラシックに戻るASP日、これらのデフォルトはそれぞれ15秒と30秒でした 、今日の.NETのデフォルトが何であるかわかりません。

SQL Serverには、独自のタイムアウトセットがあります。次に例を示します。

  • リモートクエリのタイムアウト。デフォルトは600秒(10分)です。
  • リモートログインタイムアウト。デフォルトは10秒です。
  • クエリ待機。デフォルトは-1(25 xクエリコスト)です。
  • フルテキストプロトコルハンドラのタイムアウト。デフォルトは60秒です。

ここでは、システムのこれらの値を確認できます。

SELECT * FROM sys.configurations
WHERE configuration_id IN (1519,1520,1541,1557);

@@LOCK_TIMEOUT(デフォルトは-1(無限大))もあります。これは、SQL Serverがブロックされたリソースを待機する時間です。 SET LOCK_TIMEOUT を使用して、特定のセッションに対してこれを上書きできます。 詳細はこちら

私が推測するデッドロックもこのカテゴリーに入る可能性があります。システムは5秒ごとにデッドロック状況をスキャンしますが、関連する要求のいずれがいつ開始されたかに関連してデッドロックがいつ発生するかを決定する魔法の公式はありません。これは、SQL Serverが最も古いトランザクションを優先させないためです。 DEADLOCK_PRIORITY および被害者をロールバックするために必要なリソースの推定量に基づいて被害者を選択します。 詳細はこちら

メモリ許可のタイムアウトもあります(リソースガバナーを使用してカスタマイズできます)。同時実行性に応じて、要求されたすべてのメモリを取得する前にタイムアウトに達しても、クエリは必ずしも失敗しません。割り当てられた量で実行されるため、効率が低下する可能性があります。失敗した場合は、おそらくメッセージ8645が表示されます。

これらのエラーメッセージを確認することで、SQL Server内で発生する可能性のある他の潜在的なタイムアウトシナリオのアイデアを得ることができます。

SELECT message_id, [text]
  FROM sys.messages 
  WHERE language_id = 1033 
  AND ([text] LIKE '%timeout%' OR [text] LIKE '%time out%')

ただし、可能なすべてのタイムアウト状況の完全かつ網羅的なリストを提供しようとすることは、誰にとっても実用的、実行可能、または生産的だとは思いません。あなたが抱えている問題を解決するのではなく、おそらく決して決して起こらないであろう問題の束全体を時期尚早に解決するのではなく...

13
Aaron Bertrand

ここでは、3つの異なる概念に触れています。うまくいけば、これは彼らが何であるかについての良い説明を与え、そこからあなたはそれらを避ける方法を理解できるでしょう。

Blocking(別名ライブロック)
クエリがロックを取得しようとしたが、ロックが許可される前にロックキューで待機しなければならない場合、ブロッキングが発生します。他のプロセスがキューの前にあるロックを解放するのを待っているため、クエリが何も実行していないように見えることがあります。ロックが特定の順序で取得されるとcanがデッドロックを引き起こす(以下で説明します)。

タイムアウト
タイムアウトは、クライアントがリソースを要求し、応答を待つときに発生します。一定の時間内に応答がない場合、永久に待機するのではなく、クライアントによってエラーが発生します。タイムアウトはさまざまな理由で発生する可能性があります(ブロッキング、または大量の処理を実行するクエリ、またはネットワークが非常に遅い、または...)。ただし、結局のところ、クライアントが待機していて、望まないことを決定したためです。これ以上待つこと。

デッドロック
デッドロックは、2つ以上のプロセスがリソースのロックを保持しているときに発生し、他のプロセスが保持しているリソースのロックも取得しようとします。これにより、どちらのクエリも終了またはロールバックしない限り、どちらのクエリも続行できないという状況が発生します。これがデモビデオ here でどのように機能するかを示しました。

1
Jon Seigel