• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:SELECT文でタイムアウトが起こります。)

SELECT文でタイムアウトが起こります

このQ&Aのポイント
  • SQLServer2005とASP.NET C#の環境で開発を行っています。1つのクラスに2つのクエリを呼び出す処理を書いていますが、2ユーザが同じタイミングで検索を行うとタイムアウトが発生してしまいます。また、まれにデッドロックも起こります。
  • 問題の原因として、SQLServerではSelectのたびにlockがかかるため、他の方法を探しているということが挙げられます。ただし、テーブルには他ユーザからの更新もあり得るため、「WITH(NOLOCK)」を使用することはできないです。
  • この問題の解決策としては、トランザクション分離レベルを変更することが考えられます。ただし、現在の設定は規定値であるため、他の解決策を模索しているとのことです。

質問者が選んだベストアンサー

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

2ユーザともタイムアウトになるのですか? タイムアウトがハードウェアのリソースやコネクションの競合などではなくて、テーブルロックにより発生しているという結論はどうやって導き出しましたか? READ COMITTEDのロックヒントなしのSELECT同士でブロッキングやデッドロックが発生するパターンが思い当たらないので。 NOLOCKをつけたらタイムアウトしなくなるか試してみるのがいいと思います。 で、本当にロックが原因で、ダーティリードは避けたいとなると、参照処理ということを踏まえてスナップショット分離レベルを使うくらいかと思います。

apk_2008
質問者

補足

>2ユーザともタイムアウトになるのですか? はい。ほぼ同じタイミング、かつ10秒程度、タイムアウトになります。 >タイムアウトがハードウェアのリソースやコネクションの競合などではなくて、テーブルロックにより発生しているという結論はどうやって導き出しましたか? 私もjamshid6さんと同じように、ブロッキングやデッドロックが発生するとは思っていなくて、前述したようにSELECTでlockがかかるというサイトを見た、と言うだけです。多数のユーザがアクセスするシステムのため、2ユーザの処理だけでリソースのせいとは考えにくく、安易にそのサイトを受け入れたと言うところです。 >NOLOCKをつけたらタイムアウトしなくなるか試してみるのがいいと思います。 そうですね、NOLOCKをつけて同じ現象が発生しなければ、ロックが原因だったと言え、対処法としてはスナップショット分離レベルに設定すればよいと言うことになりますね。 jamshid6さん、ありがとうございました。分離レベルでもちょっと分からないところがあるのですが、ロックが原因だと判明したら質問させていただきます。

その他の回答 (1)

回答No.2

デッドロックが原因であれば、 SELECTだけの方は SET LOCK_TIMEOUT 10000 (ミリ秒) 等を利用して設定値を小さくしエラーにしてみたらどうですか? 逆にデッドロックが原因ではない場合は 設定値を大きくし、エラーが発生しないように待つ設定にしてみたら如何でしょうか? 経験上ですがSQLServerの場合ロックのエスカレーションのせいでいきなりデッドロックが発生する事があります。 エスカレーションのせいでテーブルロックにまで膨らんだりします。 (以前プレミアサポートに確認したら時はPKeyやindexを指定していればありえないと言っていましたが、発生してしまっていました。) 実行中にロックレベルやロックの状態を確認するとはっきりとするかもしれませんね。 ※2008では設定でエスカレーションを外せるようにはなってるみたいですね。 更新を伴うSELECTだとしたら、処理の順番を統一しているか確認が必要かもしれません。 処理の入り口で同じテーブルにテーブルロックをかけるように命令すれば確実にデッドロックは発生しなくなると思います。 (必ず待ちが発生し処理を平行して行えなくなるデメリットは発生します。)

apk_2008
質問者

お礼

jamshid6さん、tomo197608さん 遅くなりましたが、アドバイスありがとうございました。

関連するQ&A