通过JDBC进行的SQLite:选择

时间:2019-02-04 09:57:06

标签: sqlite jdbc

从表中选择后尝试写入表时,出现错误代码SQLITE_BUSY。在插入之前,请正确关闭select语句和结果。

如果我要删除选择的部分,则插入效果很好。这就是我没有得到的。根据文档SQLITE_BUSY的意思是,一个不同的进程或连接(在这里显然不是这种情况)正在阻塞数据库。

没有运行SQLite管理器。此外,jdbcConn是与我拥有的数据库的唯一连接。也没有并行运行的线程。

这是我的代码:

    try {
        if(!jdbcConn.isClosed()) {
            ArrayList<String> variablesToAdd = new ArrayList<String>();

            String sql = "SELECT * FROM VARIABLES WHERE Name = ?";

            try (PreparedStatement stmt = jdbcConn.prepareStatement(sql)) {
                for(InVariable variable : this.variables.values()) {
                    stmt.setString(1, variable.getName());
                    try(ResultSet rs = stmt.executeQuery()) {
                        if(!rs.next()) {
                            variablesToAdd.add(variable.getName());                 
                        }
                    }
                }
            }

            if(variablesToAdd.size() > 0) {
                String sqlInsert = "INSERT INTO VARIABLES(Name, Var_Value) VALUES(?, '')";
                try(PreparedStatement stmtInsert = jdbcConn.prepareStatement(sqlInsert)) {
                    for(String name : variablesToAdd) {
                        stmtInsert.setString(1, name);
                        int affectedRows = stmtInsert.executeUpdate();

                        if(affectedRows == 0) {
                            LogManager.getLogger().error("Error while trying to add missing database variable '" + name + "'.");
                        }
                    }
                }

                jdbcConn.commit();
            }
        }
    }
    catch(Exception e) {
        LogManager.getLogger().error("Error creating potentially missing database variables.", e);
    }

此操作在int affectedRows = stmtInsert.executeUpdate();上崩溃。现在,如果我删除第一个块(并手动向variablesToAdd列表中添加一个值),则该值会很好地插入数据库中。

我想念什么吗?我没有正确关闭ResultSet和PreparedStatement吗?也许我对它的错误视而不见了太久了。

编辑:还可以在单​​独的线程中执行选择操作。但这不是解决方案。关闭前面的语句后,我是否试图以太快的速度插入数据库?

Edit2:我遇到了busy_timeout,它承诺要使更新/查询等待指定的时间,然后再返回SQLITE_BUSY。我尝试像这样设置繁忙的超时时间:

if(jdbcConn.prepareStatement("PRAGMA busy_timeout = 30000").execute()) {
    jdbcConn.commit();
}

executeUpdate()函数仍然立即返回SQLITE_BUSY。

1 个答案:

答案 0 :(得分:1)

我很傻。 我被删除选择语句起作用(仍然不确定为什么这样起作用,可能是糟糕的时机)这一事实所困扰,以至于我错过了使用同一文件的另一个线程的想法。

使两个线程都使用相同的java.sql.Connection,现在一切正常。

感谢您将我推向正确的方向@GordThompson。不知道导致我发现问题的jdbc:sqlite::memory:选项。