【问题标题】:Database file is locked (SQL Exception in Java)数据库文件被锁定(Java 中的 SQL 异常)
【发布时间】:2018-03-27 23:17:42
【问题描述】:

在我的代码中,每当我调用以下函数时,都可以访问数据库 Emitter。该函数基本上是从数据库中提取数据并将其存储在变量中。

public void fillEmitterDataLists()
{
    EmitterStructVo emitter = new EmitterStructVo();

    try {
        stmt = dbConn.createStatement();

        rs = stmt.executeQuery( "SELECT * FROM Emitter;" );
        while ( rs.next() ) {
            emitter = new EmitterStructVo();
            model.emitterList.add(rs.getString("E_ID"));

            String pri = rs.getString("PRI_ID");
            String pw = rs.getString("PW_ID");
            String rf = rs.getString("RF_ID");
            String reps = rs.getString("Reps");
            String interval = rs.getString("Interval");

            Statement stmt1;
            stmt1 = dbConn.createStatement();

            ResultSet rs1 = stmt1.executeQuery("SELECT * FROM PRI where PRI_ID = '" + pri + "';");
            model.priList.add(rs1.getString("PRI_Values"));

            int priType = Integer.parseInt(rs1.getString("PRI_TYPE"));

            rs1 = stmt1.executeQuery("SELECT * FROM PW where PW_ID = '" + pw + "';");
            model.pwList.add(rs1.getString("PW_Values"));

            rs1 = stmt1.executeQuery("SELECT * FROM RF where RF_ID = '" + rf + "';");
            model.rfList.add(rs1.getString("RF_Values"));
            stmt1.close();
            rs1.close();

        }
        stmt.close();
        rs.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

但是如果我在调用上面的函数后执行下面的代码,就会出现Emitter数据库文件被锁定的错误。然而,如果我之前不调用上述函数,则以下代码可以正常工作。所以,很明显,问题出在 fillEmitterDataLists() 函数上。

Class.forName("org.sqlite.JDBC");
Connection dbConn = DriverManager.getConnection("jdbc:sqlite:FssDb.db");
Statement stmt = dbConn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM Emitter where E_ID = '" + name + "';");

现在我已经按照关于堆栈溢出的类似问题中的建议关闭了所有语句和结果集,所以我不知道为什么它仍然会产生异常。

请帮忙?

【问题讨论】:

  • 仅供参考:您以错误的方式关闭了StatementResultSet。关闭 Statement 应该(并非所有 JDBC 都这样做)关闭 ResultSet。因此,如果Sqlite 正确执行,关闭stmt1 将关闭rs1。下一条语句会产生错误(我认为)。请注意,这应该在 finally 语句中正确完成(或使用 try-with-resource
  • 不,它不会产生错误。我在多个地方的语句之后关闭结果集,它不会在任何地方产生错误。我还删除了关闭结果集的行,但这也没有帮助。
  • 我从来没有说过这是原因……但如果您想得到答案,请不要尝试打开 基于文件的数据库 两次。如果你不从上面的方法中关闭dbConn并尝试与第二个sn-p建立新的连接,这将是不可能的,同时只有一个Connection是可能的。最好在 SQlite DB 上使用 Singleton 以防止出现任何问题
  • 哦,谢谢!这就是答案。显然,我一次创建了多个连接,这些连接甚至可以正常工作。但这一次,它拒绝工作。
  • 这不太可能,但我从未尝试使用 SQLite 同时打开两个连接。您可以共享相同的连接引用。

标签: java sql sqlite jdbc locked


【解决方案1】:

基于answer 关于多线程和 SQLITE。

您会发现SQlite 不支持多连接。原因是每当您请求数据库上的连接时,都会在该文件上设置一个锁,您需要关闭连接以释放该锁。只有这样您才能打开新连接。

因此您要么必须关闭上述方法中提供的dbConn,要么只是共享连接。

我建议您查看Singleton pattern 以正确管理连接。

【讨论】:

    【解决方案2】:

    SQLite 对文件锁定特别挑剔。尝试关闭连接,以便每个函数打开自己的连接,使用它并在之后关闭它。看看this answer对你有没有帮助。

    【讨论】:

    • 答案的链接没有帮助,但关闭了连接。谢谢! :)
    猜你喜欢
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多