Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting [SQLITE_BUSY] database file is locked with select statements

If I run multiple threads against my web app I get:

java.sql.SQLException: [SQLITE_BUSY]  The database file is locked (database is locked)
    at org.sqlite.DB.newSQLException(DB.java:383)
    at org.sqlite.DB.newSQLException(DB.java:387)
    at org.sqlite.DB.execute(DB.java:339)
    at org.sqlite.PrepStmt.executeQuery(PrepStmt.java:75)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)

I do know that only one thread can write to a sqlite database but I'm only reading from the database. So why do I get this error message ?

BTW: My connection pool looks like this:

<bean class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close" id="dataSource">
    <property name="driverClassName" value="${database.driverClassName}" />
    <property name="url" value="${database.url}" />
    <property name="username" value="${database.username}" />
    <property name="password" value="${database.password}" />
    <property name="initialSize" value="1" />
    <property name="maxActive" value="2" />
    <property name="maxIdle" value="1" />
    <property name="poolPreparedStatements" value="true" />
</bean>

The setup is: Java 1.6, Tomcat 7.0.34, Spring 3.2, Hibernate 3.6.9 and sqlite3 3.7.2

Regards Roger

like image 713
rogergl Avatar asked Dec 15 '12 09:12

rogergl


People also ask

How do you unlock a .DB file?

If you want to remove a "database is locked" error then follow these steps: Copy your database file to some other location. Replace the database with the copied database. This will dereference all processes which were accessing your database file.

Does sqlite lock?

SQLite version 3 seeks to avoid writer starvation through the use of the PENDING lock. The PENDING lock allows existing readers to continue but prevents new readers from connecting to the database. So when a process wants to write a busy database, it can set a PENDING lock which will prevent new readers from coming in.

How do I stop sqlite busy?

The only safe way to remove a WAL file is to open the database file using one of the sqlite3_open() interfaces then immediately close the database using sqlite3_close().


4 Answers

After some googling I found that it is a bad practice to use multiple connections when connecting to SQLite. See

http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking

Set your poolsize maxactive to 1 and try out.

like image 146
sorencito Avatar answered Sep 30 '22 14:09

sorencito


There should be only ONE connection with your application. you can use this to ensure.

public class SqliteHelper {
private static Connection c = null;
public static Connection getConn() throws Exception {
    if(c == null){
    Class.forName("org.sqlite.JDBC");
    c = DriverManager.getConnection("jdbc:sqlite:D:/test.db");
    }
    return c;
    }
}
like image 40
bowman han Avatar answered Sep 29 '22 14:09

bowman han


Note also that this may happen if you accidentally forget to close your connection:

Connection connection;
try {
  Statement statement = connection.createStatement();
  ResultSet resultSet = statement.executeQuery(QUERY);
  if (resultSet.next()) { /* do something */ }
catch (SQLException e) { /* handle exception */ }
finally {
  if (connection != null) {
    try {
      connection.close(); // <-- This is important
    } catch (SQLException e) {
      /* handle exception */
    }
  }
}

While the first database connection may work well once the server is started, subsequent queries may not, depending on how the connection pool is configured.

like image 9
johanwannheden Avatar answered Sep 30 '22 14:09

johanwannheden


For anyone who's having issues with it in WSL2:

Happened to me when I was using WSL2 & Datagrip, even tho the database wasn't busy.

It turns out that Datagrip has tried to connect to the database file that existed inside WSL2 via Windows' sqlite3.

Moving the file from WSL2 to a Windows file directory seems to solve this issue

like image 9
Eliya Cohen Avatar answered Sep 30 '22 14:09

Eliya Cohen