- PR -

DELETE後のINSERTが行えない

投稿者投稿内容
どっちの丸ちゃん
会議室デビュー日: 2003/05/21
投稿数: 7
投稿日時: 2003-05-21 10:50
はじめまして。、みなさんお手柔らかに。

環境:Win2000, Tomcat4.1.24, JDK1.4.0.3, PowerGres

JSPでリストページ、入力ページ(モーダル画面)、登録処理ページの3つのページを作成しています。
リストページは、DBからResultSetで結果を一覧表示しています。
ここから入力ページに遷移して値の入力を行い、登録ページにsubmitしてDB登録します。
リストページでは、チェックボックスを設けて削除も行えるようにしました。

処理後の画面遷移。
INSERT → 入力ページはそのままで、入力項目をクリアして連続登録を行えるようにする。
UPDATE → 入力ページを閉じ、リストページをreload。
DELETE → リストページをreload。

INSERT,UPDATE,DELETEの個々の処理は行えるのですが、
DELETEした後、そのレコードをINSERTすると登録が行えません。
別のレコードで削除したレコードのキーにUPDATEは行えます。

以下登録ページのソース抜粋

〜中略〜

Class.forName(JDriver);
handler = DriverManager.getConnection(PGUrl, PGUser, PGPasswd);
handler.setAutoCommit(false);
sts = handler.createStatement();

〜中略〜

switch (vMode.charAt(0)) {
case 'n':
//INSERT文を作成
query = "INSERT 〜 "
break;
case 'u':
//UPDATE文を作成
query = "UPDATE 〜 "
break;
case 'd':
//DELETE文を作成
query = "DELETE 〜 "
break;
}

〜中略〜

try {
result = sts.executeUpdate(query);
handler.commit();
} catch (Exception ex) {
handler.rollback();
} finally {
if (sts != null) { sts.close(); }
if (handler != null) { handler.close(); }
}

初心者なので何が悪いのかがよく分かりません。
どのたかご指導お願いします。




_________________
ふうた
大ベテラン
会議室デビュー日: 2001/08/23
投稿数: 198
お住まい・勤務地: 岡山
投稿日時: 2003-05-21 12:01
引用:

どっちの丸ちゃんさんの書き込み (2003-05-21 10:50) より:

DELETEした後、そのレコードをINSERTすると登録が行えません。
別のレコードで削除したレコードのキーにUPDATEは行えます。




上のちょっと意味がわかりません。

・DELETEした(はずの)レコードと同じプライマリキーのレコードがINSERTできない
・DELETEした(はずの)レコードと同じプライマリキーのレコードがUPDATEできる
ということでしょうか?

だとすると、単にレコードが消えていないだけだと思います。

DELETEした(はずの)後に、テーブルの中身を直接確認してみてはどうでしょう?


あと、例外が発生したときの処理が単にロールバックだけとなっていますが、どういう例外が発生しているのか確認できるようにしたほうがよいと思います。
どっちの丸ちゃん
会議室デビュー日: 2003/05/21
投稿数: 7
投稿日時: 2003-05-21 13:14
ふうたさんレスありがとうございます。

説明不足でした。
以下の3レコードがあるとします。
キー
・a
・b
・c

「c」をDELETE後、新たに「c」をINSERTすると
「a」「b」しか表示されない(DBの中身も一緒)。
DELETEした直後にDBの中身を見ても「c」は存在しません。
「c」以外のキー(d,e,f,etc)はINSERT出来ます。

UPDATEの件ですが、上記の例で説明するとDELETE後「b」 → 「c」にUPDATEを行うということを
言いたかったのですが、言葉が足りませんでした。
現在色々ソースを変えながら試していたら、この現象(UPDATE)は現れなくなったのですが、
同様のことをすると「b」が削除されてしまうという現象が発生しています。

推測なのですが、正しくcommitが行われていないのではないかと思い、
その線で調査しています。

それと例外処理の件ですが、今後注意したいと思います。

_________________
どっちの丸ちゃん
会議室デビュー日: 2003/05/21
投稿数: 7
投稿日時: 2003-05-21 14:28
自己レスです。

最初の投稿には詳しく載せていなかったのですが、
登録処理後のページ遷移を以下のように行っていました。

switch (vMode.charAt(0)) {
case 'n': //新規登録時
%>
<jsp:forward page="〜">
<jsp:param name="〜" value="〜" />
</jsp:forward>
<%
break;
case 'u': //更新時
%>
<jsp:forward page="〜">
<jsp:param name="〜" value="〜" />
</jsp:forward>
<%
break;
case 'd': //削除時
%>
<jsp:forward page="〜">
<jsp:param name="〜" value="〜" />
</jsp:forward>
<%
break;
}

forwardをやめてresponse.sendRedirectにしたらうまくいきました。

うまくいったのは良いのですが、どうしてかがよく分かりません。
分かる方がいたら教えてください。

_________________
ふうた
大ベテラン
会議室デビュー日: 2001/08/23
投稿数: 198
お住まい・勤務地: 岡山
投稿日時: 2003-05-21 17:13
引用:

どっちの丸ちゃんさんの書き込み (2003-05-21 14:28) より:

forwardをやめてresponse.sendRedirectにしたらうまくいきました。




これは本当でしょうか?
(いろいろ修正しているうちに直ったということはないですか?)
今正常に動作しているソースで response.sendRedirectをforwardに変えたら動かなくなるのでしょうか?(2つの現象を報告されていますが、どちらも発生するようになるのでしょうか?)


ちなみに引用されているforwardのソースは、最初の投稿にあるソースのどの部分に記述されていますか?(前後関係がよく分かりません。)


あと、前に戻りますが、

引用:

どっちの丸ちゃんさんの書き込み (2003-05-21 10:50) より:

別のレコードで削除したレコードのキーにUPDATEは行えます。




引用:

どっちの丸ちゃんさんの書き込み (2003-05-21 13:14) より:

UPDATEの件ですが、上記の例で説明するとDELETE後「b」 → 「c」にUPDATEを行うということを言いたかったのですが、言葉が足りませんでした。
現在色々ソースを変えながら試していたら、この現象(UPDATE)は現れなくなったのですが、同様のことをすると「b」が削除されてしまうという現象が発生しています。




ここも意味がわかりません。

・プライマリキーが「c」のレコードを消した後、プライマリキーが「b」のレコードを
 プライマリキー「c」に変更できる
 
とおっしゃられているように見えますが、別に普通の動作のように見えます。
そうすると『これの現象が発生しなくなって』が意味不明になってしまいます。

『同様のことをすると「b」が削除されて』というのも、プライマリキーを変更しようとするとレコードが削除されると読めてしまい、これまた意味不明です。
(そんなことがありえるのでしょうか?!)
どっちの丸ちゃん
会議室デビュー日: 2003/05/21
投稿数: 7
投稿日時: 2003-05-22 09:47
ふうたさん、度々レスありがとうございます。

どうも人に説明するのが下手でして・・・

>今正常に動作しているソースで response.sendRedirectをforwardに変えたら動かなくなるのでしょうか?(2つの現象を報告されていますが、どちらも発生するようになるのでしょうか?)

forwardからresponse.sendRedirectに変更したら正常に動作するようになりました。
逆に戻したらDELETE後のINSERTは出来ませんでした。


>ちなみに引用されているforwardのソースは、最初の投稿にあるソースのどの部分に記述されていますか?(前後関係がよく分かりません。)

下のソースの後ろに続いています。
try {
result = sts.executeUpdate(query);
handler.commit();
} catch (Exception ex) {
handler.rollback();
} finally {
if (sts != null) { sts.close(); }
if (handler != null) { handler.close(); }
}


>・プライマリキーが「c」のレコードを消した後、プライマリキーが「b」のレコードを
> プライマリキー「c」に変更できる
>とおっしゃられているように見えますが、別に普通の動作のように見えます。
>そうすると『これの現象が発生しなくなって』が意味不明になってしまいます。
>『同様のことをすると「b」が削除されて』というのも、プライマリキーを変更しようとするとレコードが削除されると読めてしまい、これまた意味不明です。
(そんなことがありえるのでしょうか?!)

流れで説明すると、
@「c」をDELETEする
・a
・b

A「c」をINSERTする
・a
・b
//変化なし

B「b」を「c」にUPDATEする
・a
・c
//最初の現象ではこういう状態になりました。
//確かに普通の動作なのですが、INSERTが出来ないのにUPDATEが
//行えるのが何故なのかなと思いました。

Cforwardからresponse.sendRedirectに変える直前のソースでBを行う。
・a
//「a」のみが表示される。「b」があたかも削除されたように見える。
//ここでの自分の表現の仕方がまずかったですね。
//Bの現象が出なくなったのは、ちょっと分かりません。

以上ですが、こんな説明で分かって頂けたでしょうか?


_________________
ふうた
大ベテラン
会議室デビュー日: 2001/08/23
投稿数: 198
お住まい・勤務地: 岡山
投稿日時: 2003-05-22 14:04
現象事態は理解しました。

ただ、どうしてこういう現象になるのかはよく分かりませんね。
(提示されたソースだけ見ると問題ないような気がしますが。。。)

ちなみに下記のページは確認されたことがあるでしょうか?
http://osb.sra.co.jp/PowerGres/Tech/shared_buffers.php

あと、sendRedirectとforwardの違いというのは理解されているでしょうか?
(なぜ、変えてみようと思いました?)
どっちの丸ちゃん
会議室デビュー日: 2003/05/21
投稿数: 7
投稿日時: 2003-05-22 18:31
紹介してくれたページ拝見しました。
まだ確認していませんでした。情報ありがとうございます。

>あと、sendRedirectとforwardの違いというのは理解されているでしょうか?
(なぜ、変えてみようと思いました?)

sendRedirectとforwardの違いは、よく分かっていません。
sendRedirectはクライアントにいったん戻してから指定したURLにリダイレクトし、
forwardはクライアントに処理を戻さず、サーバー上で処理を渡すぐらいの認識しかありません。
間違っていたらすみません。

変えようと思ったのは、リストページにはMAXで表示できる件数を設けて
表示できていない部分はページングさせているのですが、
DELETEしてINSERTが出来ない状態のときに別のページに移ってから
また元のページに戻りINSERTを行ったら登録が行えたのです(普通のことですが)。
その時にcommitが正常に行われていないのではと思ったのです。
ただカンでいったん処理をクライアントに戻せばcommitされるのではないかと思ったのです。
根拠はなくあくまでカンで行った結果です。

_________________

スキルアップ/キャリアアップ(JOB@IT)