はじめまして。
SQL SERVER初心者の為、ご指導の程お願いいたします。
UPDATE文で発生するデッドロックについて教えてください。
現在、ストアドプロシージャ内で、
以下のUPDATE文を使用しています。
UPDATEテーブルA
SET 更新済フラグ='1'
WHEREロック時間 =パラメータ.ロック時間
ANDロックユーザー=パラメータ.ロックユーザー
AND ID= パラメータ.ID
※Where句に使用する、ロック時間・ロックユーザー・IDは、
キー項目では無く、インデックスも使用しておりません。
ただし、対象データを一意に識別できる項目ではあります。
このストアドを含む処理を、ほぼ同時実行すると
このUPDATE文で「LOCK TIMEOUT」が発生し、
デッドロックとなってしまいます。
UPDATEの対象となるデータ件数は、ともに500~600件です
また、対策としましてロックのヒント文を下記のように設定し、
WHERE句に設定している、ロック時間・ロックユーザー・IDに
対して、インデックスを作成してみましたが、
同様に、デッドロックが発生してしまいます。
UPDATEテーブルA (with rowlock)
SET 更新済フラグ='1'
WHEREロック時間 =パラメータ.ロック時間
ANDロックユーザー=パラメータ.ロックユーザー
AND ID= パラメータ.ID
SQL Serverに詳しい方、お力になっていただければ、光栄です。
よろしくお願いいたします。
A 回答 (7件)
- 最新から表示
- 回答順に表示
No.7
- 回答日時:
回答が遅れました。
色々なアドバイスが出てきていますので、一度切り分けて
考えてみてはいかがでしょうか。
・SPから当該UPDATE文のみを抜き出して実行してもデッドロックになるか?
・TABLOCKにした場合でも同じか?
・ロックの待ち時間を長くしてみてもTIMEOUTが発生するか?
をまずは試してみてください。
その結果によって原因がわかるかもしれませんし、
別のアドバイスが出来るかもしれません。
No.6
- 回答日時:
SQLServerは、
重複していなく、インデックスになっているキー(主キー含む)、
に対して、WHERE句を設定すると行ロックとなり、
重複している OR インデックスになっていない、フィールドに対して、
WHERE句を設定するとページロックまたは、全件検索となる仕組となっています。
デッドロックは、複数のSQL文が発行された時におきる現象ですが、
今回、この「UPDATE」以外の、SQL文はどうなのでしょうか?
基本的にSQLServerは、適切なテーブル設計、チューニングができていれば目だった、デッドロック、遅延等ほとんどおきないように、なってはいますが・・・
基本中基本が原因であれば、RDBのスキル習得からオススメします。
No.5
- 回答日時:
>Where句に使用する、ロック時間・ロックユーザー・IDは、
>キー項目では無く、インデックスも使用しておりません。
>ただし、対象データを一意に識別できる項目ではあります
あなたには一意と判断できても、RDBMS側には一意と判断できず、
全件検索することになります。
>このUPDATE文で「LOCK TIMEOUT」が発生し、
>デッドロックとなってしまいます
SQL Serverのデッドロックには詳しくないですが、RDBMSによっては
「たすき掛け」と「排他待ちが一定時間を越えた」を切り分けて
メッセージを出してくれるものも少なくありません。
今回の場合は、後者ではないのでしょうか?
>UPDATEの対象となるデータ件数は、ともに500~600件です
UPDATEを500~600件発行するとき、COMMITは発行していないのですよね?
インデクスがなければ、物理順で同じ経路を繰り返し探すことになるので
タイムアウト等が発生して当然だと思いますが?
>ロック時間・ロックユーザー・IDに
>対して、インデックスを作成してみました
どういうインデクスを定義したのでしょうか?
(ロック時間,ロックユーザー,ID)で1本のインデクスを定義したの
でしょうか?
chukenkenkouさん、ご返答ありがとうございます。
いくつかご回答につきまして、いくつか質問をさせてください。
>あなたには一意と判断できても、RDBMS側には一意と判断できず、
全件検索することになります。
これについてですが、ロック時間・ロックユーザー・IDが、
テーブルのキー項目となっている場合は、全件検索は行われない
という認識でよろしいでしょうか?
初歩的な質問で申し訳ありません。
>どういうインデクスを定義したのでしょうか?
>(ロック時間,ロックユーザー,ID)で1本のインデクスを定義したの
でしょうか?
なにぶん初心者なもので、インデックスの作成は手探り状態で
行いました。
エンタープライズマネージャーより、該当テーブルのデザインより、
(ロック時間,ロックユーザー,ID)のインデックスを作成しました。
1本のインデックスも作成することが可能なのですか???
また、インデックスのよい作成方法をご存知であれば、
教えてください。
現在、下記のようなテーブルレイアウトです。
識別コード,年度,月度,○○番号 ・・・・・ ロック時間,ロックユーザー,ID
※識別コード,年度,月度,○○番号までが、キー項目となります。
よろしくお願いします。
No.4
- 回答日時:
自分も初心者ではありますが同じようなことがあったので参考までに書かせていただきます。
確かLOCKTIMEOUTはデッドロックではなかったような気がします。
LOCKTIMEOUTということは順序的に先になった更新処理が遅すぎて後続が待ちきれずにTIMEOUTしたのではないでしょうか?
トランザクション開始処理時のオプションで処理待ち時間が変えられるはずなので、試してみてはいかがでしょうか?
以上、参考になれば幸いです。
No.3
- 回答日時:
再度#1です。
SQL Serverの環境が手元に無いので試していませんが、
With句の指定って
×:UPDATE テーブルA (with rowlock)
↓
○:UPDATE テーブルA with (rowlock)
じゃないかなぁ・・・
ちゃんと行ロックになっているか、EnterPriseManagerなり
sp_lockで見るなりして確認してみてください。
この回答への補足
ご回答ありがとうございます。
すみません。記述を間違えていました。
プログラム上は、with (rowlock)となっています。
No.2
- 回答日時:
#1です。
追加質問にお答えします。SQL Serverは通常、ページ単位のロックを行います。
(確か7.0からはオプティマイザが動的に最適なロック単位を
選択してくれるようになったかも・・・)
ですので、行A・Xが違っても同一ページ(確かデフォルトは8KB)に
入っていれば、Aを更新ロックする際にXもロックされます。
しかし、行ロックオプションを指定しているとのことですので
それは起こらないはず。なのでTransactionを開放してないからとか
ストアド内で他のテーブルも更新していて順序がたすきがけに
なったとか、の原因を疑った方が良いとおもいます。
早急なご回答ありがとうございます。
度々の質問で大変恐縮ですが、処理内容を確認したところ、、、
SP内の処理では、同一テーブルに更新しにいく処理は存在しますが、
同一行への更新は行われないものとなっています。
ヒント文、ROWLOCKを使用しておりますが、
同一テーブルへの更新が行われる場合、デッドロックの可能性が
考えられるということでしょうか???
よろしくお願いいたします。
No.1
- 回答日時:
Updateの行の順序は保証されていません。
(特にPキー以外の列を含む条件の場合)
なので、処理A・処理Bで同一行が複数対象になった場合
更新行がたすきがけになればデッドロックが発生します。
処理A・Bで絶対に同一行が更新対象になりませんか?
ロック・ユーザーIDが重なることはなさそうだけど・・・
どうしてもダメなら行ロックではなくテーブルロックにして
試してみてください。
ご回答ありがとうございます。
テーブルロックを試してみます。
ご回答に関しまして、1つ質問させていただいても
よろしいでしょうか?
>処理A・処理Bで同一行が複数対象になった場合
>更新行がたすきがけになればデッドロックが発生します。
処理A・処理Bとも、同一行への更新は無いのですが、
やはり、たすきがけ状態になり、
デッドロックが発生してしまうのでしょうか?
例)処理A実行時
行A・B・Cが更新対象行
処理B実行時
行X・Y・Zが更新対象行
よろしくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
歩いた自慢大会
「めちゃくちゃ歩いたエピソード」を教えてください。 長時間でも長距離でも結構です。
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
SELECT文でのデッドロックに対しての対処方
SQL Server
-
更新ロックとデッドロック
SQL Server
-
同じSELECT文同士でのデッドロックが発生
Oracle
-
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
トランザクション中にSELECTし...
-
SELECT FOR UPDATE にトランザ...
-
SELECT文でのデッドロックに対...
-
SELECT文でタイムアウト...
-
「マスタ」と「テーブル」の違...
-
ACCESS2007 フォーム 「バリア...
-
2つのテーブルから条件に一致...
-
重複するキーから一番古い年月...
-
ビューで引数を使いたい
-
Access VBA 読み取り専用かチェ...
-
アクセス 日付抽出(年月のみ)...
-
ユニオンクエリで繋げられるテ...
-
Accessにインポートしたら並び...
-
Inner join と Left joinの明...
-
Delphiのデータベースについて
-
SQL Serverのテーブル追加を、A...
-
ACCESSのODBCリンクテーブルに...
-
Accessのリンクテーブルについて
-
ユニオンクエリの結果をテーブ...
-
mysql IN句に1データだけ指定...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SELECT時の行ロックの必要性に...
-
SELECT文でのデッドロックに対...
-
accessのロック
-
AccessShareLock はどの程度気...
-
SQLServer Insertが遅い
-
MongoDBのデータ更新はDBを排他...
-
Oracleの排他制御について教え...
-
DB2のロック調査
-
同一トランザクションの中でテ...
-
ExcelからAccess2013DBを更新す...
-
同時書き込み
-
INSERTにおいてロック処理は必要か
-
更新ロックとデッドロック
-
SELECT文でタイムアウト...
-
DB2でSelectした時(rollback,c...
-
UPDATE文で発生するデッドロッ...
-
トランザクション中にSELECTし...
-
SELECT FOR UPDATE にトランザ...
-
ADOで排他ロックがうまくいかない
-
排他ロックしたレコードが、別...
おすすめ情報