获取sqlite繁忙异常[SQLITE_BUSY]数据库文件被锁定(数据库被锁定)

Posted

技术标签:

【中文标题】获取sqlite繁忙异常[SQLITE_BUSY]数据库文件被锁定(数据库被锁定)【英文标题】:Getting sqlite busy exception [SQLITE_BUSY] The database file is locked (database is locked) 【发布时间】: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 是否使用准备好的语句足以避免注入?我添加了更多代码 请在您的问题中添加您创建连接的方式,并阅读***.com/questions/13891006/… 【参考方案1】:

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

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

写入数据库文件

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

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

https://sqlite.org/lang_transaction.html

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

【讨论】:

以上是关于获取sqlite繁忙异常[SQLITE_BUSY]数据库文件被锁定(数据库被锁定)的主要内容,如果未能解决你的问题,请参考以下文章

暴露的 SQLite 连接因 SQLITE_BUSY 而失败

sqlite遇到database is locked问题的完美解决

sqlite遇到database is locked问题的完美解决

多线程如何并发访问SQLite数据库

从 ContactsContract 表中获取数据时出现 SQLITE 异常

为啥我的语句因资源繁忙异常而失败?