「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>SQL Server]] * 目次 [#o588c3c7] #contents *概要 [#w2a150bb] SQL Server でのデッドロック発生時の対応方法ついて説明します。 *前提知識 [#mad75c2d] 基本的に、ロックのたすき掛けで発生しています。 このため、 -「[[DBMSのロック・分離戦略と同時実行制御]]」 -「[[SQL Server でのロック・タイムアウト]]」 で説明したように、SQL Serverのロッキングのメカニズムについて知っておく必要があります。 例えば、SQL Serverは、 -参照処理にもロック(共有ロック)をかける。 -スキャンにより広範囲にロックがかかる。 -ロック・エスカレーションにより広範囲にロックがかかる。 等と言った所でしょうか。 *分析方法 [#q7915695] **ロックの確認 [#sd2cb677] 「[[SQL Server でのロック・タイムアウト]]」で説明した方法で、~ ロックの状態を確認しつつ、デッドロックが発生していないかを確認します。 **SQLプロファイラ [#vaa65e1a] [[SQLプロファイラを用いてデッドロックを確認する方法>SQLプロファイラ(SQLトレース)#ff404b4c]] *対応方法 [#o2db9efa] **アプリ側の設計上の問題 [#u763480d] ロック法で実装されたRDBMSを利用するアプリケーションとしての設計上の問題が無いかを確認します。 ***更新ロックの活用 [#sf836f28] OracleとSQL Serverの更新ロックは、「更新データの消失」を防ぐ役割で使用される。~ #「更新データの消失」とは参照したデータが、同一トランザクション中で更新されてしまう事。~ SQL Serverの場合、「更新データの消失」の防止は、共有ロックのホールドでも事足りる。~ このため、SQL Serverの更新ロックは「デッドロック」防止のためと言われる。 ***デッドロックの回避 [#n9ab1375] [[更新ロックの活用>#sf836f28]]以外にも、デッドロックを回避のために検討すべきことがあります。 +同じ順序でオブジェクトにアクセスする(CRUD表などを利用)。~ +トランザクション内でのユーザの対話をなくす。~ +トランザクションを短くして、1つのバッチ内に収める。~ +業務に問題が無ければ、できるだけ低い分離レベルを使用する。 **DBMSの機能上の問題 [#a28eafa6] ロック法で実装されたRDBMSの機能を問題と考える場合、以下のような対策もあります。 ***エスカレーションの抑止 [#v4fcc63b] ロックのエスカレーションの抑止をする。~ [[SQL Server のロックのエスカレーション]] ***多バージョン法への切替 [#d8321c40] 多バージョン法へ切り替える。~ [[DBMSのロック・分離戦略と同時実行制御]] **その他の対応 [#hdd32fbc] ***タイムアウトと同列に扱う [#kb59b73a] レアケースであれば、ロック・タイムアウト、コマンド・タイムアウトと同様に~ リトライ可能なエラー(業務続行可能なエラー)として設計しておくのも手です。 ***SQL Serverの問題 [#i5b94247] 並列クエリ等、ロック以外の原因で~ [[並列クエリ>SQL Server のファイル・グループ#z5226928]]等、ロック以外の原因で~ デッドロックが発生する可能性もあります。~ 原因によっては、パッチでFIXすることもあります。 この場合、エラー番号が異なるようです。 -通常:1205 -並列クエリ:8650 -サポート技術情報(Microsoft Knowledge Base) --クエリ内の並列処理を使用するクエリを実行すると、~ 8650 のエラー メッセージが表示されます。~ http://support.microsoft.com/kb/837983/ja --[BUG] 並列クエリが応答を停止する、~ または 8650 エラー メッセージが表示される~ http://support.microsoft.com/kb/317821/ja --[FIX] クエリを並列実行すると、~ クエリ自体で検出されないデッドロックが発生する~ http://support.microsoft.com/kb/315662/ja *参考 [#v2410b52] -SQL Server 技術情報 - デッドロックの解決方法~ http://support.microsoft.com/kb/832524/ja -デッドロック~ http://msdn.microsoft.com/ja-jp/library/ms177433.aspx --デッドロックの検出と終了~ http://msdn.microsoft.com/ja-jp/library/ms178104.aspx -SQL実践講座(最終回):SQL Serverで「デッドロック」を回避する - @IT~ http://www.atmarkit.co.jp/ait/articles/0304/11/news003.html -[SQLServer]デッドロックを発生させてログを拾ってみる 大都会で働く新人SEの日記~ http://t-wata.com/?p=221 ---- Tags: [[:データアクセス]], [[:SQL Server]], [[:障害対応]], [[:性能]], [[:デバッグ]]