【问题标题】:Getting sqlite busy exception [SQLITE_BUSY] The database file is locked (database is locked)获取sqlite繁忙异常[SQLITE_BUSY]数据库文件被锁定(数据库被锁定)
【发布时间】:2020-10-12 19:26:30
【问题描述】:

EDIT :: 关闭结果集和查询语句解决了我的问题

我正在尝试通过 java 和 sqlite 构建一个聊天应用程序。当我尝试将新记录插入数据库中的表时,我面临数据库锁定错误消息。在这里我尝试在他们第一次注册时添加新用户:

public void addNewUser(String username,String password)  {
    StringBuilder sb=new StringBuilder("INSERT INTO loginInfo VALUES('");
    sb.append(username);
    sb.append("','");
    sb.append(password);
    sb.append("')");
    try {
        Statement statement = connection.createStatement();

        statement.execute(sb.toString());
        statement.close();
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
}

我首先检查 dosUserExist() 函数中是否已经存在相同的用户名:

private void handleSignup(String[] tokens) throws IOException, SQLException {
    if(tokens.length==3){
        String username=tokens[1];
        String password=tokens[2];
        String msg=null;
        if(!dataSource.doesUserExists(username)) {
            msg="signup successful\n";
            this.login=username;
            dataSource.addNewUser(username,password);
        }
        else msg="signup unsuccessful\n";
        this.send(msg);
    }
}

我收到以下错误消息:

org.sqlite.SQLiteException: [SQLITE_BUSY]  The database file is locked (database is locked)
at org.sqlite.core.DB.newSQLException(DB.java:1010)
at org.sqlite.core.DB.newSQLException(DB.java:1022)
at org.sqlite.core.DB.execute(DB.java:861)
at org.sqlite.core.CoreStatement.exec(CoreStatement.java:80)
at org.sqlite.jdbc3.JDBC3Statement.execute(JDBC3Statement.java:53)

在执行所有其他查询后,我已关闭该语句。我该怎么做才能解决这个错误?

【问题讨论】:

  • 我们需要更多代码来给出答案。另外,不要将原始字符串发送到您的数据库!!!!您的聊天应用程序将持续大约 5 分钟,您将成为 SQL 注入的受害者。说真的,解决这个问题。 owasp.org/www-community/attacks/SQL_Injection
  • 是否使用准备好的语句足以避免注入?我添加了更多代码
  • 请在您的问题中添加您创建连接的方式,并阅读stackoverflow.com/questions/13891006/…

标签: java sqlite jdbc


【解决方案1】:

您有其他进程或线程正在数据库中写入并持有 RESERVED 锁,或者您已打开但未关闭 TRANSACTION

http://www.sqlite.org/draft/matrix/lockingv3.html

写入数据库文件

一次只有一个进程可以持有保留锁。但其他进程可以继续读取数据库 保留 RESERVED 锁。

如果要写入的进程无法获得RESERVED 锁,它必须意味着另一个进程已经有一个保留锁。 在这种情况下,写入尝试失败并返回 SQLITE_BUSY。

https://sqlite.org/lang_transaction.html

任何访问数据库的命令(基本上,任何 SQL 命令, 除了一些 PRAGMA 语句)将自动启动事务 如果尚未生效。自动启动事务 在最后一条 SQL 语句完成时提交。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    相关资源
    最近更新 更多