4

私は単純なコードを使用して Oracle DB の単一行を更新しています。クエリは単一行のみを更新しますが、実行は stmt.executeUpdate() でハングします。

例外はスローされませんが、コントロールはそこでハングします。

以前は同じコードが正常に機能していたので、ここで迷ってしまいました。

  try {
      DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
      conn = DriverManager.getConnection(url,username,pwd);
      stmt = conn.createStatement();
      String sql = "update report set status =" +"'"+NO+"'"+ " where name=" +"'"+ name+"'"+ " and user_id=" +"'"+sub+"'"; 
      System.out.println(sql);          
      stmt.executeUpdate(sql)
4

4 に答える 4

13

このように変数を連結してステートメントを作成しないでください。これにより、SQL インジェクションにさらされることになります。さらに、各ステートメントは、ハード解析を必要とする新しいステートメントとして Oracle によって認識されるため、パフォーマンスの問題が発生する可能性があります。代わりに、 PreparedStatement を使用してください。

ただし、あなたの場合、それはあなたの問題の原因ではないと思います。単純な更新がハングする場合、ほとんどの場合、次のいずれかの理由が原因です。

  1. 行は別のトランザクションによってロックされています。
  2. 索引付けされていない外部キーとして別の表によって参照されているキーを更新しています。
  3. テーブルには、多くの作業を行う ON UPDATE トリガーがあります。

あなたが最初のケースにいると確信しています。Oracle では、主に一貫性の理由から、複数のユーザーが同じ行を同時に更新することを防止しています。これは、変更された行がロックされている場合、DML ステートメントが別のトランザクションを待機することを意味します。ブロックしているトランザクションがコミットまたはロールバックするまで待機します。

before を実行して行を更新する前に、常に行をロックすることをお勧めしますSELECT ... FOR UPDATE NOWAIT。行がすでにロックされている場合、これは失敗します。この行が現在別のセッションによってロックされていることをユーザーに伝えることで、正常に終了できます。

また、トランザクションがコミットされていない状態で終了しないようにする必要があります。すべてのセッションは、終了する前に変更をコミットまたはロールバックする必要があります (自動コミットは使用しないでください)。

于 2013-08-14T12:37:39.437 に答える
1

JDBC PreparedStatement Java ドキュメントを使用する

  Class.forName("org.apache.derby.jdbc.ClientDriver");
  Connection con = DriverManager.getConnection
  ("jdbc:derby://localhost:1527/testDb","name","pass");
  PreparedStatement updateemp = con.prepareStatement
  ("insert into emp values(?,?,?)");
  updateemp.setInt(1,23);
  updateemp.setString(2,"Roshan");
  updateemp.setString(3, "CEO");
  updateemp.executeUpdate();
于 2013-08-14T12:01:33.387 に答える
-1

代わりに PreparedStatement を使用してください

http://www.mkyong.com/jdbc/jdbc-preparestatement-example-insert-a-record/

ステートメントの場合、サーバーが構文をチェックするたびに時間がかかるため、PreparedStatementに進みます

于 2013-08-14T12:02:04.553 に答える