5

我在 servlet 应用程序中使用sqlite数据库和java.sql类将一些数据批量插入到数据库中。有连续四次插入不同类型的数据。每个看起来像这样:

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也许这个错误还有其他原因(因为我刚刚发现插入非空字段时会抛出关于数据库未找到或配置不当的异常)?

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

您必须准备您的 Statement 并在之后创建批次conn.setAutoCommit(false);

于 2012-08-30T10:40:47.867 回答
1

从 servlet 运行它时,您必须确保 的使用Connection是同步的。多个请求可以Connection几乎同时将其设置为不同的自动提交模式。如果您Connection每个请求使用一个,这将不是问题。否则,用临界区保护上述部分。

适用于 tomcat / eclipse 的调试提示。

1) 为您的应用服务器启用 JDPA 调试。在 tomcat 中,您可以通过在 catalina.sh / catalina.bat 中添加以下行来做到这一点:

 set JPDA_ADDRESS=8000
 set JPDA_TRANSPORT=dt_socket

2)重启应用服务器

3) 使用 eclipse 连接到您的应用程序服务器。“调试为”->“远程 Java 应用程序”

4)在上面的代码中设置一个断点。

5) 运行小服务程序。

于 2012-08-30T10:45:30.290 回答