- ベストアンサー
SELECT文でタイムアウトが起こります
- SQLServer2005とASP.NET C#の環境で開発を行っています。1つのクラスに2つのクエリを呼び出す処理を書いていますが、2ユーザが同じタイミングで検索を行うとタイムアウトが発生してしまいます。また、まれにデッドロックも起こります。
- 問題の原因として、SQLServerではSelectのたびにlockがかかるため、他の方法を探しているということが挙げられます。ただし、テーブルには他ユーザからの更新もあり得るため、「WITH(NOLOCK)」を使用することはできないです。
- この問題の解決策としては、トランザクション分離レベルを変更することが考えられます。ただし、現在の設定は規定値であるため、他の解決策を模索しているとのことです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
2ユーザともタイムアウトになるのですか? タイムアウトがハードウェアのリソースやコネクションの競合などではなくて、テーブルロックにより発生しているという結論はどうやって導き出しましたか? READ COMITTEDのロックヒントなしのSELECT同士でブロッキングやデッドロックが発生するパターンが思い当たらないので。 NOLOCKをつけたらタイムアウトしなくなるか試してみるのがいいと思います。 で、本当にロックが原因で、ダーティリードは避けたいとなると、参照処理ということを踏まえてスナップショット分離レベルを使うくらいかと思います。
その他の回答 (1)
- tomo197608
- ベストアンサー率14% (3/21)
デッドロックが原因であれば、 SELECTだけの方は SET LOCK_TIMEOUT 10000 (ミリ秒) 等を利用して設定値を小さくしエラーにしてみたらどうですか? 逆にデッドロックが原因ではない場合は 設定値を大きくし、エラーが発生しないように待つ設定にしてみたら如何でしょうか? 経験上ですがSQLServerの場合ロックのエスカレーションのせいでいきなりデッドロックが発生する事があります。 エスカレーションのせいでテーブルロックにまで膨らんだりします。 (以前プレミアサポートに確認したら時はPKeyやindexを指定していればありえないと言っていましたが、発生してしまっていました。) 実行中にロックレベルやロックの状態を確認するとはっきりとするかもしれませんね。 ※2008では設定でエスカレーションを外せるようにはなってるみたいですね。 更新を伴うSELECTだとしたら、処理の順番を統一しているか確認が必要かもしれません。 処理の入り口で同じテーブルにテーブルロックをかけるように命令すれば確実にデッドロックは発生しなくなると思います。 (必ず待ちが発生し処理を平行して行えなくなるデメリットは発生します。)
お礼
jamshid6さん、tomo197608さん 遅くなりましたが、アドバイスありがとうございました。
補足
>2ユーザともタイムアウトになるのですか? はい。ほぼ同じタイミング、かつ10秒程度、タイムアウトになります。 >タイムアウトがハードウェアのリソースやコネクションの競合などではなくて、テーブルロックにより発生しているという結論はどうやって導き出しましたか? 私もjamshid6さんと同じように、ブロッキングやデッドロックが発生するとは思っていなくて、前述したようにSELECTでlockがかかるというサイトを見た、と言うだけです。多数のユーザがアクセスするシステムのため、2ユーザの処理だけでリソースのせいとは考えにくく、安易にそのサイトを受け入れたと言うところです。 >NOLOCKをつけたらタイムアウトしなくなるか試してみるのがいいと思います。 そうですね、NOLOCKをつけて同じ現象が発生しなければ、ロックが原因だったと言え、対処法としてはスナップショット分離レベルに設定すればよいと言うことになりますね。 jamshid6さん、ありがとうございました。分離レベルでもちょっと分からないところがあるのですが、ロックが原因だと判明したら質問させていただきます。