ASP+SQL Serverで切実に困ってます。
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNGたぶんすっごい基本的なことだと思うんで知ってる人いたらタスケテ。
ASP+MS SQL Serverで作ったWebのサービスに異常発生。
調べてみたらユニークでなきゃいけないIDがかぶってました。
どうやら
1.一番大きいIDを引っ張ってくる。
↓
2.それに+1する
↓
3.+1したIDをつけてINSERT。
っていうところで1→3が終わる前に他のユーザが1の処理を
はじめるとIDがかぶるってことがわかりました。
(ためしに自分で2台同時にボタンおしたらかぶりました)
会社でほかにわかる人がいないので凄い基本っぽい気がする
この問題が解決できません(涙
ロックとかトランザクションって調べたんですけどいまいち意味がわかってない
せいかうまくいきません。
17日の正午までメンテナンス中っていうページに差し替えて
しのいであるんだけどこのままじゃ・・・。
0032デフォルトの名無しさん
NGNGASP の VBScript には On Error GoTo ないぞ(正確には On Error GoTo 0,
On Error Resume Next だけ使える)。
003327
NGNGそーか、ごめん。
IIS+ASPにはもう何年も触ってないのに適当なこと書いちゃった。
そうすると、この場合のエラー処理はどうするんだろう。On Error Resume Next
しておいて、ConnectionオブジェクトのErrorsプロパティをチェックすれば
できるのかな?
0034デフォルトの名無しさん
NGNGつーか、そんな枝葉じゃなくて、根本的なトコロが間違ってるのよ。
0035デフォルトの名無しさん
NGNGまじで、痛すぎるよ。
カキコ控えてROMに徹したほうが身のためだよ。
00361
NGNG先の処理をまっててくれる⇒ROCKにしたい所存。
↑こういう現状です。
>9
で言ってるようにWITH(UPDLOCK)ってのがつかえないんすが・・・
>Error401
調べ中に見つけたんすけどロールバックされたら@@IDENTITYは元に戻らないそうです。
0037デフォルトの名無しさん
NGNGそして、そのtableに
update dummy set dummy = max + 1 where dummy = max;
としてupdateを発行しないの?他のセッションが同時期におなじupdate文を
発行したなら、dummy = maxのrowは存在しなくなるから変更は行われない。
変更行がなかった場合にはもう一度maxの取得をして変更できるまで繰り返す。
update文の実行はアトミックであることが保証されてるからmax + 1もアトミックな
値が返るぞ。
0038デフォルトの名無しさん
NGNG人を批判する前に自分の考えを示しな。
27の方が多少なりともえらいぞ。
ちなみにおれはASP使いじゃないからしらん。
0039Error401
NGNGうーん、update dummy文が1文1トランザクションだとすると、連番保証が
なくなるので、IDENTITYを使うのと変わらないし、
更新対象のupdate文と同じトランザクションに入れるのなら、
select max(id) + 1と変わらない気がするんですけど・・・。
>>38
えーと、>>27のコードは、本質的に>>1となんら変わりがないので
批判されてるんじゃないかと思います。
解決法はすでに出尽くしてると思うし。
0040デフォルトの名無しさん
NGNGASPとかそうゆう問題じゃないんだよ。
それがわからないお前も逝ってよし。
さすが、Error401氏
004127
NGNG>>39
すいません。後で気が付いたんですが、その通りですね。
それで、昔同じようなことをしたのを思い出しました。そのときの解決法は
>>37のようにMAX値保存テーブルを作成し、ストアドプロシージャで
1. 現在のMAX値を更新用カーソルで取得する
2. インクリメントしたMAX値をそのカーソルを使用して更新する
を1トランザクションで実行し、成功したら更新したMAX値を返す、という方法を
取りました。
00421
NGNGありがとうございます。なんとなくわかってきたかも。
発番用のテーブルを用意するってのはそういうことだったんすね。13
そんで今わからないのがその重複しちゃ困るIDで同時に
もう1個のテーブルをINSERTまたはUPDATEしてるんですけど
「そのカーソルだと複数にまたがったトランザクションできません」
みたいなエラーがでます。
(ロックタイプ、カーソルは 3.3 です。)
0043便乗質問でスミマセン
NGNGある条件で、11件目から5件のレコードを取り出す場合、
PostgreSQLなら
SELECT * FROM syohin WHERE tanka < 10000 OFFSET 10 LIMIT 5;
MySQLなら、
SELECT * FROM syohin WHERE tanka < 10000 LIMIT 10,5;
MS-SQL2000Serverの場合はどうしたらいいんでしょう?
いろいろ調べたのですが分かりません。
0044便乗質問でスミマセン
NGNGある条件で、11件目から5件のレコードを取り出す場合、
PostgreSQLなら
SELECT * FROM syohin WHERE tanka < 10000 OFFSET 10 LIMIT 5;
MySQLなら、
SELECT * FROM syohin WHERE tanka < 10000 LIMIT 10,5;
Oracle8の場合はどうしたらいいんでしょう?
いろいろ調べたのですが分かりません。
ちなみに、
WHERE ROWNUM BETWEEN 11 AND 15
はダメでした。
0045
NGNGマルチスレッド知らない厨房がサーバーサイドやっちまったのかWW
0046
NGNG0047
NGNG〜
UPDATE //ロック解除
だったような気がする。
0048
NGNG0049デフォルトの名無しさん
NGNG2 INSERT 直後に @@IDENTITY で番号を取得。
のコードの書き方教えて
WHERE ... AND (ROWNUM >10) AND (ROWNUM <16)
だったような気がする。
0051デフォルトの名無しさん
NGNGもうちょっとくわしく説明して下さい
なぜ、別に一個 1rowだけのMAXナンバーを格納したTableを作らんの?
そして、そのtableに
update dummy set dummy = max + 1 where dummy = max;
としてupdateを発行しないの?他のセッションが同時期におなじupdate文を
発行したなら、dummy = maxのrowは存在しなくなるから変更は行われない。
変更行がなかった場合にはもう一度maxの取得をして変更できるまで繰り返す。
update文の実行はアトミックであることが保証されてるからmax + 1もアトミックな
値が返るぞ。
005243
NGNGそれはつまり、マルチスレッドというもので解決できるのでしょうか?
ありがとうございます。後は自分で調べてみます。
0053デフォルトの名無しさん
NGNGしかし、落とし穴があって、システムが異常終了するとこの連番が狂うので、DBCCで修正してやらないといけない
0054デフォルトの名無しさん
NGNG他のセッションが同時期におなじupdate文を
発行したなら、dummy = maxのrowは存在しなくなるから変更は行われない
この理由がよくわからないのですが
0056仕様書無しさん
NGNGふたつのセッションで同じ値の max (仮に10とする) を取得してしまったとしても、
そのうちのひとつのセッションで、先に dummy = max + 1 ( dummy = 10 + 1 ) に
書き換えれば、dummy = 10 の行は存在しなくなるでしょ。
もうひとつのセッションで dummy = 10 の行への書き込みを試みても、そんな行は
もうないから、書き込みは行えないというわけ。
0057デフォルトの名無しさん
NGNG複数のクライアントからアクセスすると、「容量を超えていたため、
新規トランザクションを作成できません。」というエラーが返ってきます。
そこで、もしMSDEのトランザクション領域(デフォルト)のサイズをご存知の方が
いらっしゃいましたら、教えていただけないでしょうか?
よろしくお願いします。
0058縞栗鼠(シマリス)の親方
NGNG汚物入れを物色して女子生徒の使用済みタンポン・ナプキン等を
個人的に収集しているというのは事実。
中央高等学院では
生徒及びその保護者の個人情報を名簿図書館等に売却しています。
中央高等学院 http://chs-f.com/index.html 中央高等学院福岡校
http://www.chuo-school.ac/
0059名無しさん@Emacs
NGNGFAQなのレス。
(>50だと期待する結果にならんと思われ。
WHERE句のROWNUMは条件が入るとみんな偽になってしまうので。)
11件目から5件ってことは11件目から15件目を取得すればいいので、
SELECT * FROM syohin WHERE tanka < 10000 AND ROWNUM <= 15
MINUS
SELECT * FROM syohin WHERE tanka < 10000 AND ROWNUM < 11
つまり、15件以下のデータから10件以下をマイナスすればいいのレス。
0060名無しさん@Emacs
NGNGあと、間違ってた...鬱だ...
最後は ROWNUM < 11 ですわな...
0061デフォルトの名無しさん
NGNGMAX+1に適当なダミーデータを放り込んでおいて、INSERTの変わりにUPDATE
すべきかと思われ。
SQL*Serverにあるのかどうか知らんが、SWQENCEつかうのが一番いいとおもわれ。
0062デフォルトの名無しさん
NGNG方法1.1〜3をBEGIN TRANSACTIONとCOMMITで囲む。(これにより排他がかかる)
方法2.ユニークインデックスにして、重複エラー時は適当な時間をおいてリトライさせる。
方法3.1〜2を3のトリガー処理に書きSQL分を一つにする。トリガー処理は一意であるのでOKになる。
■ このスレッドは過去ログ倉庫に格納されています