使用select语句锁定[SQLITE_BUSY]数据库文件

rog*_*rgl 24 java sqlite hibernate jpa

如果我对我的网络应用程序运行多个线程,我得到:

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)
Run Code Online (Sandbox Code Playgroud)

我知道只有一个线程可以写入sqlite数据库,但我只是从数据库中读取.那么为什么我会收到此错误消息?

顺便说一句:我的连接池看起来像这样:

<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>
Run Code Online (Sandbox Code Playgroud)

设置是:Java 1.6,Tomcat 7.0.34,Spring 3.2,Hibernate 3.6.9和sqlite3 3.7.2

关心罗杰

Eli*_*hen 25

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.

将文件从 WSL2 移动到 Windows 文件目录似乎可以解决此问题


sor*_*ito 17

经过一些谷歌搜索后,我发现连接到SQLite时使用多个连接是一种不好的做法.看到

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

将poolize maxactive设置为1并尝试.


bow*_*han 11

应用程序应该只有一个连接.你可以用它来确保.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)


joh*_*den 5

另请注意,如果您不小心忘记关闭连接,可能会发生这种情况:

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 */
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

虽然第一个数据库连接可以在服务器启动后运行良好,但后续查询可能不会,具体取决于连接池的配置方式.