データーベースに関して、知識があまりないもので、的外れなことや
情報不足があったらすみません。
SQLServer2005で同一のUPDATE文を2人で実行しようとしたところ、変換デッドロックが発生してしまいました。
該当するSQL文は
1 SELECT ~ FROM xxxx FOR UPDATE OF ~
2 UPDATE xxxx
という2つのSQL文です。このSQLはアプリケーションが自動で発行生成しているSQLなので自分では変更は出来ないです。
エラーを確認するため、Profilerで確認したところ、以下のようになっていました。
<inputbuf>
FETCH API_CURSOR000000000000FA5C
</inputbuf>
</process>
</process-list>
<resource-list>
<ridlock fileid="1" pageid="435113" dbid="11"
objectname="xxx.dbo.xxxx(テーブル名)" id="lock4eccf240" mode="U"
associatedObjectId="54650898874368">
<owner-list>
<owner id="processb491f8" mode="S"/>
<owner id="processdf4898" mode="U"/>
<owner id="processdf4898" mode="U"/>
</owner-list>
<waiter-list>
<waiter id="processdf4898" mode="X" requestType="convert"/>
<waiter id="processb491f8" mode="U" requestType="wait"/>
</waiter-list>
</ridlock>
</resource-list>
</deadlock>
</deadlock-list>
共有ロック → 更新ロック → 排他ロックという順番でロックをかけようとしたところ、更新ロックから排他ロックに変換しようとしたところで
エラーになっているみたいです。
これらを解消するのに何か良い方法はありますでしょうか?
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
SQLやProfilerのトレースではなく、具体的に、これらの処理を実装している、ソースを見せて頂けませんか?
(まずい箇所は加工して頂いて結構なので)
そういう意味で、この補足をお願いしてたのですが、言い方が悪くてすいません。
ソースを見ない限り、トランザクションの単位もわかりませんし、
分離レベルの状態もどうなっているのか予測がつきません。
>>また、トランザクションは、1つ目のSELECT FROM UPDATE FORと
>>2つめのUPDATE文で違うトランザクションなのでしょうか?
>>(SQL Profilerからの結果では予測ができませんでした)
>COMMITまでが一つのトランザクションならば、一つのトランザクションだと思います。
だと思いますだと、はっきりしたことがご回答できないので、やはりストアドやSQL、もしくは、他のプログラミング言語(VBやC#等)で記述されたものが公開されてないと、情報が少なくて、回答に困ってしまうと思いますので、情報をもう少しだけ精査して頂き、そのうえで対処方法をご回答いたします。
すべては、「ソースに始まり、ソースで終わる」 です。
宜しくお願いします。
この回答への補足
説明がうまく出来るか分からないですが、
使用しているのはパッケージソフトです。
GUI操作で、入力フィールドやプッシュボタン等、いくつかの部品を組み合わせて画面を作成していきます。
作った画面を動かす時に、どのようなSQLが発行されているかを知る手段は
プロファイラー等で見るしかないです。
ただ、別のアプローチでデッドロックを解消出来そうです(画面の構成を変える)。
なので、うまくいくようでしたら、この問題をクローズにしようと思います。
うまく説明できてないのと、情報をあまりだせない中で、お付き合いしていただいて、大変ありがとうございました。
No.1
- 回答日時:
下記、宜しかったら情報頂けますか?
・トランザクションの分離レベルがわかれば教えて下さい。
(具体的に)
READ UNCOMMITTED(非コミット読み取り)
READ COMMITTED(コミット済み読み取り)
REPEATABLE READ(再読み込み可能読み取り)
SERIALIZABLE(直列化)
・共有ロック → 更新ロック → 排他ロック
のイメージがわかないので、具体的にどのようなコードで
これらのロックを実現したのか教えて下さい。
・また、トランザクションは、1つ目のSELECT FROM UPDATE FORと
2つめのUPDATE文で違うトランザクションなのでしょうか?
(SQL Profilerからの結果では予測ができませんでした)
それから、推測になりますが、恐らく、SELECT FROM UPDATE FORで
対象テーブルに対し、XLOCKかUPDLOCKなどのロックヒントを与えるか
トランザクションの分離レベルを変更することでデッドロックを回避することができますので、問題のSQLやプログラムを可能な範囲で構いませんので、UPして頂けますか?
宜しくお願いします。
この回答への補足
御回答ありがとうございます。自分の分かる範囲で答えていきます。
前提として、このトランザクションはデータを保存するときに、アプリケーションが自動で発行しますが、アプリケーションはブラックボックスなので、発行するSQL文は変更等は出来ないです。
現状では、問題がアプリ、SQLServer、設定のいずれの問題なのか区別出来ていない状態です。
問題になってるSQLのトレースログは
「http://groups.google.co.jp/group/deadlock_SQLser …」
にExcel形式で上げておきました。
シートが2つあり、1つ目が問題のSQLを単独で実行したときのトレースログで、2つ目が1つ目のSQLを二人で同時に実行したときに発生するデッドロックのトレースログです。
・トランザクションの分離レベルがわかれば教えて下さい。
書いた時点では、READ COMMITTED(コミット済み読み取り)を使っていましたが、
現在はREAD COMMITTED SNAPSHOTを使っています。理由はアプリ側がSNAPSHOTを推薦しているようです。
ただ、READ COMMITTED SNAPSHOTを使っても、デッドロックは相変わらず発生しています。
・共有ロック → 更新ロック → 排他ロックのイメージがわかないので、具体的にどのようなコードで
これらのロックを実現したのか教えて下さい。
発行されているSQL文は2つのようです。
1 SELECT xxxxxx FROM TABLE_NAME WHERE xxxxxx=@P1 FOR UPDATE OF xxxxxx
2 UPDATE TABLE_NAME SET xxxxxx=@P1 WHERE xxxxxx=@P2
対象としているテーブルは同じテーブルです。
自分もログを見ただけで合っているか分からないのですが、
「共有ロック - 獲得」→「更新ロック - 獲得」→「共有ロック - 解除」
→「排他ロック - 獲得」→ 「更新ロック - 解除」→「排他ロック - 解除」というように推移しているように見えます。
詳しくはログを見ていただくと分かると思います。
・また、トランザクションは、1つ目のSELECT FROM UPDATE FORと
2つめのUPDATE文で違うトランザクションなのでしょうか?
(SQL Profilerからの結果では予測ができませんでした)
COMMITまでが一つのトランザクションならば、一つのトランザクションだと思います。
情報不足があるようでしたら出来るだけお伝えするつもりです。
何か分かることがあるようでしたら是非教えていただければと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(データベース) 更新クエリをリンクデータベーステーブルに実行し実行時エラー3362固有インデックスに重複する値が含ま 1 2022/09/21 11:44
- PHP PHPでCSVを出力するさいに、ループの中で前の行の値を変更したい 3 2022/10/27 17:44
- HTML・CSS CSS のみのタブ切り替えについて 1 2023/01/11 16:47
- Access(アクセス) アクセス 有効なフィールド名、または式として認識できませんのエラー 3 2022/08/19 11:53
- MySQL SQLで日付別のIDを生成するには 3 2022/10/09 10:34
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- PHP アコーディオンPHPが上手くいかない 3 2022/07/15 16:29
- Oracle sqlで質問です。 Aテーブルの情報をBテーブルに更新かけたいです。 やりたいことは、Bテーブルの受 1 2023/05/17 11:17
- MySQL SQLです。こんな感じですか?あってますか? うまくいきません教えてくださいお願いします 1 2023/07/08 15:27
- Oracle sqlで質問です。 aテーブルとbテーブルがあり、下記のsqlで取得したidとnameに一致しないレ 1 2022/04/20 20:34
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SELECT文でのデッドロックに対...
-
SELECT時の行ロックの必要性に...
-
ExcelからAccess2013DBを更新す...
-
SELECT文でタイムアウト...
-
排他ロックしたレコードが、別...
-
AccessShareLock はどの程度気...
-
SQL Server2000:排他的ロック...
-
デットロックとFOR UPDATE
-
トランザクション中にSELECTし...
-
パススルークエリでのロックに...
-
Oracleの排他制御について教え...
-
accessのロック
-
更新ロックとデッドロック
-
SQLServer Insertが遅い
-
「マスタ」と「テーブル」の違...
-
[ BETWEEN ] vs [ >= AND <= ]
-
ACCESSのSQLで、NULLかNULLでな...
-
【SQLServer】IS NULLのパフォ...
-
クエリのキャンセルがいつにな...
-
2つのテーブルから条件に一致...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
MySQLがPostgreSQLより優れてい...
-
SELECT時の行ロックの必要性に...
-
accessのロック
-
SELECT文でのデッドロックに対...
-
Oracleの排他制御について教え...
-
INSERTにおいてロック処理は必要か
-
SQLServer Insertが遅い
-
UPDATE文で発生するデッドロッ...
-
AccessShareLock はどの程度気...
-
同時書き込み
-
同一トランザクションの中でテ...
-
SELECT FOR UPDATE にトランザ...
-
更新ロックとデッドロック
-
ExcelからAccess2013DBを更新す...
-
排他ロックしたレコードが、別...
-
トランザクション中にSELECTし...
-
DB2のロック調査
-
DB2でSelectした時(rollback,c...
-
SQLServerの明示的なロックの仕...
-
SELECT文でタイムアウト...
おすすめ情報