C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: SQLServer2003 行ロックの方法


(過去ログ 55 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■31125 / inTopicNo.1)  SQLServer2003 行ロックの方法
  
□投稿者/ 肩P (1回)-(2009/01/15(Thu) 15:16:30)

分類:[VB6 以前] 

VB6とSQLServer2003を使用しています

クライアントPC5台で同じタイミングでサーバーのテーブルにSELECT・UPDATE・INSERTしに行った際にタイミングのせいなのか分かりませんが、SERVER側で重複キーのエラーが出てしまいます。

SQLプロファイラ等を使用して確認してみたところ、PC1台の処理(SELECT・UPDATE・INSERT)が終了する前に次のPCの処理が入ってきていることに原因があるみたいでした。

SQL文にてさまざまなLOCKを試してはみたもののどうしてもうまくいきません。

どなたかのお力をお貸ししていただけたらと思います

よろしくお願い致します。
引用返信 編集キー/
■31129 / inTopicNo.2)  Re[1]: SQLServer2003 行ロックの方法
□投稿者/ 囚人 (311回)-(2009/01/15(Thu) 15:41:33)
SQL Server に 2003 はない、というのはおいといて
どういうテーブル構成にどういう処理をしたいのかで、答えが変わるので、もう少し詳細情報をください。

引用返信 編集キー/
■31131 / inTopicNo.3)  Re[2]: SQLServer2003 行ロックの方法
□投稿者/ 肩P (3回)-(2009/01/15(Thu) 16:16:36)
No31129 (囚人 さん) に返信
> SQL Server に 2003 はない、というのはおいといて
> どういうテーブル構成にどういう処理をしたいのかで、答えが変わるので、もう少し詳細情報をください。

すみません、SERVERは2000でした。^^;

テーブルの構造は、システムを動かす上で自動更新を掛ける項目がそれぞれ1レコードずつ格納されていて、番号を管理するマスタの
ようなイメージです。

画面のボタン押下時にそのテーブルにSELECT文を投げて、取得されたレコード(番号)に+1して再度テーブルに戻します。

たとえば、テーブルに100という番号のレコードが存在しているとして、まず1台目のPCが100という値を取得します。
取得、格納後に101にしてテーブルに戻します。
2台目が101を取得し、102を戻します
3台目が102を取得し、103を戻します
       ・
       ・
       ・

と、いう様にしたいのですが、同じタイミングでボタンを押下したときにだけ複数のPCで予期せぬエラーが出ました。

この原因として考えられるのが、1台目が処理中に2台目が待機せずに同じ値を取得してそれに更新をかけようとしているためである
ことが、濃厚です。

そこで行単位でのLOCKを試みたのですが、うまくいかないので、この場を借りたという感じです


うまく伝わりましたでしょうか?
引用返信 編集キー/
■31134 / inTopicNo.4)  Re[3]: SQLServer2003 行ロックの方法
□投稿者/ 囚人 (312回)-(2009/01/15(Thu) 16:45:17)
うまく伝わりましたが、

>そこで行単位でのLOCKを試みたのですが

ここで何をしているのか知りたいです。


引用返信 編集キー/
■31139 / inTopicNo.5)  Re[4]: SQLServer2003 行ロックの方法
□投稿者/ 肩P (4回)-(2009/01/15(Thu) 16:56:48)
No31134 (囚人 さん) に返信
> うまく伝わりましたが、
>
> >そこで行単位でのLOCKを試みたのですが
>
> ここで何をしているのか知りたいです。
>
SQL文の 〜From テーブル名 と WHERE句 の間にWITH句でROWLOCKやUPDLOCK等も試してみたのですが、
うまくいっていないようだったので、今は外しています。
引用返信 編集キー/
■31147 / inTopicNo.6)  Re[5]: SQLServer2003 行ロックの方法
□投稿者/ はつね (924回)-(2009/01/15(Thu) 17:18:51)
はつね さんの Web サイト
No31139 (肩P さん) に返信

SQL Server 2000では行ロックのつもりがロックエスカレーションが発生して行ロックではなくなっている場合があります。

参考URL:
http://support.microsoft.com/default.aspx/kb/323630/ja
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=41003&forum=26&2

引用返信 編集キー/
■31151 / inTopicNo.7)  Re[3]: SQLServer2003 行ロックの方法
□投稿者/ みきぬ (334回)-(2009/01/15(Thu) 17:31:03)
No31131 (肩P さん) に返信
> 画面のボタン押下時にそのテーブルにSELECT文を投げて、取得されたレコード(番号)に+1して再度テーブルに戻します。
>
> たとえば、テーブルに100という番号のレコードが存在しているとして、まず1台目のPCが100という値を取得します。
> 取得、格納後に101にしてテーブルに戻します。
> 2台目が101を取得し、102を戻します
> 3台目が102を取得し、103を戻します
>        ・
>        ・
>        ・
>
> と、いう様にしたいのですが、同じタイミングでボタンを押下したときにだけ複数のPCで予期せぬエラーが出ました。
>
> この原因として考えられるのが、1台目が処理中に2台目が待機せずに同じ値を取得してそれに更新をかけようとしているためである
> ことが、濃厚です。
>
つまり、1台目が MAX(ID) の結果として 100 を取得して、ID=101 で INSERT しようとしている間に、
2台目が MAX(ID) の結果として 100 を取得して、同じく ID=101 で INSERT しようとしたからコケたってことであってるかしら? であれば...

案1:
・MAX(ID) を取得するときに、テーブルロックする

案2:
・MAX(ID) の取得と INSERT を同時にやる( MAX(ID)+1 で INSERT する)

案3:
・MAX(ID) を取得する前に、何か別のロックの獲得を必須にする
 ※要は、テーブルとは別のところで排他をかけておく

のどれかかな。
引用返信 編集キー/
■31152 / inTopicNo.8)  Re[4]: SQLServer2003 行ロックの方法
□投稿者/ 肩P (5回)-(2009/01/15(Thu) 17:40:48)
No31151 (みきぬ さん) に返信
> ■No31131 (肩P さん) に返信
> 案1:
> ・MAX(ID) を取得するときに、テーブルロックする
>
> 案2:
> ・MAX(ID) の取得と INSERT を同時にやる( MAX(ID)+1 で INSERT する)
>
> 案3:
> ・MAX(ID) を取得する前に、何か別のロックの獲得を必須にする
>  ※要は、テーブルとは別のところで排他をかけておく
>
> のどれかかな。

案1と案3に関しては、試してはみたものの、うまくいきませんでした。

案2は現在、挑戦中です!

ご回答ありがとうございます
引用返信 編集キー/
■31153 / inTopicNo.9)  Re[4]: SQLServer2003 行ロックの方法
□投稿者/ 囚人 (313回)-(2009/01/15(Thu) 17:44:18)
ん〜、1〜10まで手取り足取り教えるのは大変なので、どんなコードを書いているか(どんなSQL文を書いてるか)見て、「ここが間違ってますよ」と言いたいんですが。

・そもそも取得と更新が同じトランザクションでなのかそうでないのか
・悲観ロックの話したいのか、楽観ロックの話したいのか
・分離レベルはどーなってんのか(今回は関係なさげだけど)

などなど。一言で言えないんですよね。

引用返信 編集キー/
■31160 / inTopicNo.10)  Re[5]: SQLServer2003 行ロックの方法
□投稿者/ みきぬ (335回)-(2009/01/15(Thu) 18:25:04)
No31153 (囚人 さん) に返信
> ん〜、1〜10まで手取り足取り教えるのは大変なので、どんなコードを書いているか(どんなSQL文を書いてるか)見て、「ここが間違ってますよ」と言いたいんですが。
>
うんうん。

とりあえず「重複キーのエラー」だそうなので、INSERT が被ったのだと予想しましたが、
それ以上のことはさっぱり分かりません。

質問を読み直して、採番テーブルを更新しているのかなとも考えたけど…はてさて。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -