5

sqliteサーブレット アプリケーションでデータベースとクラスを使用java.sqlして、データをデータベースにバッチ挿入します。異なる種類のデータの連続した 4 つの挿入があります。それぞれ次のようになります。

PreparedStatement statement = conn
    .prepareStatement("insert or ignore into nodes(name,jid,available,reachable,responsive) values(?,?,?,?,?);");
for (NodeInfo n : nodes)
{
    statement.setString(1, n.name);
    statement.setString(2, n.jid);
    statement.setBoolean(3, n.available);
    statement.setBoolean(4, n.reachable);
    statement.setBoolean(5, n.responsive);
    statement.addBatch();
}

conn.setAutoCommit(false);
statement.executeBatch();
conn.commit();
conn.setAutoCommit(true);
statement.close();

しかし、時々私は

java.sql.SQLException: database in auto-commit mode

データベースが自動コミットモードのjava.sql.Connectionときに呼び出すと、この例外がスローされることがソースコードでわかりました。commit()しかし、以前に自動コミットをオフにしましたが、現在アプリケーションが一度だけオンになっているため、並列実行に関連する問題の場所がわかりません。

この問題をデバッグする方法はありますか? nullこのエラーには別の理由があるのではないでしょうか ( null 以外のフィールドに挿入すると、データベースが見つからないか、適切に構成されていないという例外がスローされる可能性があることがわかったためです)。

4

3 に答える 3

4

ステートメントの順序に問題ある可能性があります。データベースステートメントは次のようになります。

  PreparedStatement statement1 = null;
  PreparedStatement statement2 = null;
  Connection connection=null;

    try {
        //1. Obtain connection and set `false` to autoCommit
        connection.setAutoCommit(false);
        //2. Prepare and execute statements
        statement1=connection.prepareStatement(sql1);
        statement2=connection.prepareStatement(sql2);
        ...
        //3. Execute the statements

        statement1.executeUpdate();
        statement2.executeUpdate();

        //4. Commit the changes

        connection.commit();
        }
    } catch (SQLException e ) {
        if (connection!=null) {
            try {
                connection.rollback();
            } catch(SQLException excep) {}
        }
    }finally {
        if (statement1 != null) {
            statement1.close();
        }
        if (statement2 != null) {
            statement2.close();
        }
       if(connection != null){
          connection.setAutoCommit(true);
          connection.close();
        }
   }
于 2012-08-30T10:59:34.750 に答える
1

ステートメントを準備し、の後にバッチを作成する必要がありますconn.setAutoCommit(false);

于 2012-08-30T10:40:47.867 に答える
1

これをサーブレットから実行する場合、 の使用Connectionが同期されていることを確認する必要があります。複数の要求がConnection、ほぼ同時に別の自動コミット モードに設定される可能性があります。Connectionリクエストごとに1 つ使用する場合、これは問題になりません。それ以外の場合は、上記の部分をクリティカル セクションで保護します。

tomcat / eclipse に適用されるデバッグに関するヒント。

1) アプリケーション サーバーの JDPA デバッグを有効にします。Tomcat では、次の行を catalina.sh / catalina.bat に追加することでこれを行うことができます。

 set JPDA_ADDRESS=8000
 set JPDA_TRANSPORT=dt_socket

2) アプリケーション サーバーを再起動します。

3) Eclipse でアプリケーション サーバーに接続します。"Debug as" --> "Remote Java Application"

4) 上記のコードにブレークポイントを設定します。

5) サーブレットを実行します。

于 2012-08-30T10:45:30.290 に答える