

先日よりデッドロックが発生するようになり、確認の為にトレースログを
抽出するように設定かけたのですが、UPDATE文とSELECT文がぶつかり
デッドロックが発生している事がわかりました。
しかし、UPDATE文にはトランザクションをかけていますが
SELECT文には特にロックかけていない為、どうして起こっているのか
わかっていません。
SELECT文を読んでいる時にUPDATE文によって
レコードに変更があった為、デッドロックが発生したのでしょうか?
SELECT文にはUNLOCKをつけた方がいいのでしょうか?
プログラムはDELPHI
DBはSQLSERVER2000になります。
お忙しい所申し訳ありません。
宜しくお願い致します。
No.7ベストアンサー
- 回答日時:
#6です。
気になったの書き込みます。
参照側で考えていましたが、更新側のロック範囲は適正でしょうか?
不必要に広い範囲に排他ロックを掛けていないでしょうか。
例えば更新が select xx from yy where zz>aa for browse のようになっていると広範囲にロックが確保され要注意です。
また、更新がバッチであれば、途中コミットして排他時間を短くするなりの対策が考えられます。
とにかく参照処理も更新処理も出来るだけ範囲を小さくされることをお勧めします。
この回答への補足
度々ありがとうございます!!
更新している方は1件トランザクションかけた後
1レコードのみ更新をかけているのですが、
1テーブルずつ行っている仕様になってい為
例
トランザクション
HEAD更新 where Head_NO='111'
HEADsub更新 where Head_NO='111'
H_PAS更新 where Head_NO='111' and Head_SubNO='1'
・
・
コミット
上記のように行っている為
1テーブルに対しては絞っているはずなのですが、
トランザクションは長いイメージは正直あります・・・
No.6
- 回答日時:
#5です。
失礼しました。ROWLOCKでは改善されないですね。
意図したのは
選択行(レコードセット)に対しては結果的にはロックしないが、該当行を読むときだけはロックする。
というものです。
調べた限りではSQL Serverでは出来ないようです。すみませんでした。
(HiRDBではwithout lock waitというオプションでこれが出来ます。)
今回のケースはselectの共有ロック期間が長いため、updateがタイムアウトすると言うことですね。
だとすると、まじめに選択範囲を分割して(TOP (n)で出来ると思うのですが検証できていません)ロック時間を短くするしかないようです。
※
ちなみにREAD_COMMITTED_SNAPSHOT データベースオプションをONにするとOracleのような動作になりデッドロックが回避されます。
ただし、パフォーマンスにはMSも疑問を持っているようです。
参考意見ばかりですみませんでした。
この回答への補足
御回答ありがとうございます。
参考意見頂けるだけでも有り難いことなので、
感謝しています。
逆に何度も申し訳ないです・・・
>図したのは
>選択行(レコードセット)に対しては結果的にはロックしないが、該当行を読むときだけはロックする。
>というものです。
すいません、質問なのですが、
>該当行を読むときだけはロックする。
>というものです。
イメージだとROWLOCK は行ロックのイメージだったのですが、
>調べた限りではSQL Serverでは出来ないようです。すみませんでした
以前UPDATEで使用した際には
WITH (ROWLOCK)が使えたと思うのですが
UPDATEしか使用出来ないとかですか??
>調べた限りではSQL Serverでは出来ないようです。すみませんでした
http://support.microsoft.com/kb/323630/ja
ROWLOCK などのロック ヒントを使用しても、最初のロック プランが変更されるだけです。ロック ヒントでは、ロックのエスカレーションは防止できません。
すいません、確かに使えないようですね・・・
>まじめに選択範囲を分割して(TOP (n)で出来ると思うのですが検証できていません)ロック時間を短く>するしかないようです。
これを一度試してみます。
ありがとうございました。
No.5
- 回答日時:
select文は
インデックス→データ
の順でアクセスしますが、update文は
データ→インデックス
の順で更新するため往々にしてデッドロックとなります。
必要なければselect文でのロック(標準では掛かります)をはずすことが対策です。
行単位のロック(ROWLOCK:1行の読み込みはロックする)に粒度を小さくすれば解消すると考えますが。
この回答への補足
御回答ありがとうございます。
>select文は
>インデックス→データ
>の順でアクセスしますが、update文は
>データ→インデックス
>の順で更新するため往々にしてデッドロックとなります。
有力な情報ありがとうございます。
>行単位のロック(ROWLOCK:1行の読み込みはロックする)に粒度を小さくすれば解消すると考えますが。
SELECT文に HEAD with (ROWLOCK)を追加し
行ってみたのですが、やはりデッドロックは発生致しました・・・
もしかしたら原因自体違うのかもしれないので
HEAD with (NOLOCK)にして検証してみます。
No.4
- 回答日時:
こんにちは。
>テーブルに(UNLOCK)を行いダーティーリードしてしまえば
>ぶつからないかなと思うのですが、いかがでしょうか??
ちょっと短絡的過ぎると思いますが・・・。
ブロッキングが多発する・・・。
(これは並列処理をやってたら普通に起こるので、気にしなくてもいいです)
デッドロックが検出される・・・。
(ここ!!)
ここをきちんとトレースして、原因を見つける事が先決です。
仕様的にダーティーリードでも全然OKというなら問題ないですが、
リソーススタベーションが原因の場合、他の箇所でも発生するかも知れません・・・。
そのときになっても、UNLOCKで回避しますか???
この回答への補足
御回答ありがとうございます。
>ちょっと短絡的過ぎると思いますが・・・。
自分でもそう思います・・・
とりあえず1回UNLOCKにしてみてデッドロック発生するかテストを
してみます。
同時に
>リソーススタベーションが原因の
こちらももう少し調査をおこなってみます。
No.3
- 回答日時:
こんにちは。
>必要な個所ありましたら貼り付けますので申しつけ下さい。
必要な箇所は「全部」ですね・・・。
ログだけでなく、ハード的な環境やそれぞれの設定値、
アプリ側の作り、SQL、トランザクション管理・・・。
結局、全部見てみないとわからんです・・・ハイ。
今回提示されている並列処理では、デッドロックにはならないです・・・。
ブロッキングのみが発生し得る・・・かな。
>解放をしないとデッドロックが発生するものなんでしょうか???
発生する可能性は十分にあります。
SQL Serverは、SELECTだけでもロックエスカレーションが発生しますし・・・。
いわゆるデッドロックは、お互いが「待ち合い」で発生しますが、この待ち合いは、トランザクションのロックレベルだけでなく、メモリー、プロセス、スレッド、その他すべてにおいて発生します。
リソーススタベーションに陥っている可能性もあります。
すごく極端な例ですが・・・、
並列処理で、たくさんのプロセスが実行された場合にブロッキングが発生した。
ロックタイムアウトになったので、ロールバックしようとした。
ロールバックするためのリソースがないので、誰かがリソースを開放するまで待つしかない・・・。
デッドロック・・・。
デッドロックの原因究明と解決は、全部見てみないとわからないです・・・。
少なくとも、現在提示されている内容だけでは、まったく判断できません。
この回答への補足
何度もありがとうございます。
少ない情報ですいません・・・
そして色々教えて頂きありがとうございます。
解放をしていないか箇所ないか、一度ソース確認してみます。
DBの方ですが、いっその事
SELECTかけている方は集計しているだけなので、
テーブルに(UNLOCK)を行いダーティーリードしてしまえば
ぶつからないかなと思うのですが、いかがでしょうか??
No.2
- 回答日時:
こんにちは。
これは1204のトレース結果ですかね?
SELECT→(S)→HEAD(プラスアルファ)
UPDATE→(X)→HEAD
このような関係では、どちらが早くてもデッドロックにはなりません。
遅い方が「待つ」だけです。
トレース結果が非常に断片的で、これだけではちょっとわかりませんが・・・、
問題は「スレッドリソース」か「ロックリソース」の不足にあるのでは?
前述したように単体テーブルに対する並列処理では、いわゆるトランザクションレベルのロックは発生し得ません。
リソースの開放など、アプリ側を見直す必要があるかも知れません・・・。
デッドロックチェインのログはないんですかね?
この回答への補足
御回答ありがとうございます。
>トレース結果が非常に断片的で、これだけではちょっとわかりませんが・・・、
>問題は「スレッドリソース」か「ロックリソース」の不足にあるのでは?
断片的ですいません。
大量に出ているもので・・・
必要な個所ありましたら貼り付けますので申しつけ下さい。
>デッドロックチェインのログはないんですかね?
トレースフラグは1204,1205,3605をONにしています。
2111-16-55 09:27:49.25 spid1End deadlock search 1475 ... a deadlock was found.
上記内容が出力されています。
>リソースの開放など、アプリ側を見直す必要があるかも知れません・・・。
>デッドロックチェインのログはないんですかね?
すいません、単純にDB詳しくない為質問なのですが、
今の現象はアプリ起動している最中にデッドロック発生しましたとWINDOUWSエラー表示がされます。
リソースの開放という事はソース内にFreeして解放していないというこでしょうか??
解放をしないとデッドロックが発生するものなんでしょうか???
No.1
- 回答日時:
こんばんは。
これだけではなんとも・・・ですね。
>SELECT文には特にロックかけていない為
この場合は暗黙的に共有ロックですが。
>SELECT文を読んでいる時にUPDATE文によって
>レコードに変更があった為、デッドロックが発生したのでしょうか?
これだけではデッドロックになり得ません。
単純にUPDATE側が「待つ」状態です。
待ち切れなければタイムアウト・・・。
SELECTによる共有ロックとUPDATEによる排他ロックは共存できないので、UPDATE側を更新ロックに変更するか・・・。
根本的に1テーブルではデッドロックにはならないでしょ?
詳細が不明なので、具体的な解決策はわかりません・・・。
御回答ありがとうございます。
情報が足りずすいません。
補足です。
>単純にUPDATE側が「待つ」状態です。
>待ち切れなければタイムアウト・・・。
それがプログラムは主にSELECTをしている集計
の方でデッドロックが発生しています。
ログの見方を間違えているのかもしれませんが、下記がログ抜粋部分になります。
Input Buf: Language Event: SELECT H.AA,H.BB・・・・・・・・・
がありその後に
2100-22-15 09:27:49.25 spid1Producer: Xid Slot: 1, EC = 0x8f22000, SPID: 1, ECID: 3, Blocking
という感じで9回ほどブロックされた後に
2111-18-88 09:27:49.25 spid1Input Buf: Language Event: UPDATE HEAD SET NO = '', CODE = '・・・・
とあります。
>根本的に1テーブルではデッドロックにはならないでしょ?
>詳細が不明なので、具体的な解決策はわかりません・・・。
UPDATEを行っているプログラムがHEADテーブルのみ更新
SELECTをかけていますプログラムがJOINTを行いHEADテーブルを含み4テーブル程
一度に呼び出しています。
すいません、宜しくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle SQL update方法 2 2022/06/22 14:07
- JavaScript 電車の運賃を出すプログラムを作っています。 2 2022/06/22 09:36
- MySQL 下の画像はSQLの4大命令の性質をまとめたものであるらしいです UPDATE INSERT DELE 1 2023/06/07 15:36
- MySQL SQLについて教えて下さい。 SELECT分で、あるカラムにある日付の 半年先のデータを取って来たい 3 2022/12/07 22:28
- JavaScript HTML,JS初心者です。 2つのselectボックスが有り その選択の組み合わせにより 指定した文 3 2022/03/31 23:35
- Visual Basic(VBA) データのある範囲を選択するVBAについて 2 2022/09/03 00:20
- JavaScript セレクトボックスで配列を呼び出したい。 1 2022/07/08 20:14
- 事件・事故 2023年3月2日に発生した、JR川越線デッドロックはなぜ発生? 1 2023/03/03 13:37
- Excel(エクセル) ②Excel 簡単にシートコピーしたら前日の残高と日付を変更させたい→マクロの記録でエラーが出ます 8 2022/07/16 20:40
- その他(データベース) 更新クエリをリンクデータベーステーブルに実行し実行時エラー3362固有インデックスに重複する値が含ま 1 2022/09/21 11:44
このQ&Aを見た人はこんなQ&Aも見ています
-
同じSELECT文同士でのデッドロックが発生
Oracle
-
SELECT文でタイムアウトが起こります。
SQL Server
-
UPDATE文で発生するデッドロックについて、教えてください。
SQL Server
-
-
4
【DB】同じトランザクション内でupdateとselectをしたときの結果値
その他(データベース)
-
5
CloseとDisposeの違い
Visual Basic(VBA)
-
6
SQLについて教えて下さい with(nolock)の意味は何でしょうか?
SQL Server
-
7
SQLServer Insertが遅い
SQL Server
-
8
SQLServerでNULLを挿入したいです
SQL Server
-
9
「タイプ初期化子が例外をスローしました」エラー何?
Visual Basic(VBA)
-
10
win10で1つのフォルダ内に保存できるファイル数
ドライブ・ストレージ
-
11
Viewにインデックスは張れますか?
Oracle
-
12
タスクスケジューラからショートカットを起動させるには?
その他(プログラミング・Web制作)
-
13
Dosブロンプトでtabを出力したい
その他(プログラミング・Web制作)
-
14
SELECT 文 GROUP での1件目を取得
SQL Server
-
15
ビューにインデックスを設定できませんか?
SQL Server
-
16
DataGridViewのチェックボックスのON、OFFの判定方法
C言語・C++・C#
-
17
INSERT時にデータ登録とmaxの発番がしたい
SQL Server
-
18
共通モジュールでDBへの接続と利用方法
Visual Basic(VBA)
-
19
SQLServer sqlcmdが使えない
SQL Server
-
20
データベース関係で、データの洗い替えとはどのような事を行うことでしょう
IT・エンジニアリング
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SELECT時の行ロックの必要性に...
-
SELECT文でのデッドロックに対...
-
デットロックとFOR UPDATE
-
Oracleの排他制御について教え...
-
数値を加算する場合の処理について
-
PCとDBを更新したら、エラ...
-
INSERTにおいてロック処理は必要か
-
「マスタ」と「テーブル」の違...
-
accessのエクスポートエラーに...
-
AccessのテーブルをSQL Server...
-
ACCESS2007 フォーム 「バリア...
-
VBAの実行時エラー'2522'について
-
データの二重表示の原因
-
phpmyadminで問い合わせた結果...
-
Google検索はなぜ早い?
-
クエリのキャンセルがいつにな...
-
【SQLServer】IS NULLのパフォ...
-
SQLServer 分散トランザクショ...
-
IFで条件を分岐させてのINSERT...
-
PL/SQLでFROM句に変数を使いたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SELECT時の行ロックの必要性に...
-
SELECT文でのデッドロックに対...
-
SQLServer Insertが遅い
-
Oracleの排他制御について教え...
-
accessのロック
-
AccessShareLock はどの程度気...
-
排他ロックしたレコードが、別...
-
INSERTにおいてロック処理は必要か
-
更新ロックとデッドロック
-
SELECT文でタイムアウト...
-
max+1で初番する場合 for updat...
-
ExcelからAccess2013DBを更新す...
-
UPDATE文で発生するデッドロッ...
-
DB2でSelectした時(rollback,c...
-
DB2のロック調査
-
トランザクション中にSELECTし...
-
トランザクションとlast_insert_id
-
同一トランザクションの中でテ...
-
MongoDBのデータ更新はDBを排他...
-
SELECT FOR UPDATE にトランザ...
おすすめ情報