首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >选择后插入时通过JDBC: SQLITE_BUSY执行SQLite

选择后插入时通过JDBC: SQLITE_BUSY执行SQLite
EN

Stack Overflow用户
提问于 2019-02-04 17:57:06
回答 1查看 273关注 0票数 1

在从表中进行选择后,尝试写入表时,我得到错误代码SQLITE_BUSY。select语句和结果在insert之前已正确关闭。

如果我删除了select部分,插入就能正常工作。这就是我不明白的地方。根据文档,SQLITE_BUSY应该意味着另一个进程或连接(这里肯定不是这种情况)阻塞了数据库。

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

下面是我的代码:

代码语言:javascript
复制
    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吗?也许我对自己的错误视而不见,因为我看了太久。

编辑:在单独的线程中执行select也能起到作用。但这不可能是解决之道。在关闭前面的语句后,我是否试图过快地插入到数据库中?

Edit2:我遇到了一个busy_timeout,它承诺让更新/查询在返回SQLITE_BUSY之前等待一段指定的时间。我尝试这样设置忙碌超时:

代码语言:javascript
复制
if(jdbcConn.prepareStatement("PRAGMA busy_timeout = 30000").execute()) {
    jdbcConn.commit();
}

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

EN

回答 1

Stack Overflow用户

发布于 2019-02-05 17:29:50

我是个笨蛋。删除select语句起作用了(仍然不确定为什么起作用,可能时机不对),以至于我错过了使用同一文件的不同线程。

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

感谢您将我推向正确的方向@GordThompson。我没有意识到jdbc:sqlite::memory:选项导致我找到了问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54513666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档