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

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

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) 

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

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

           

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

关心罗杰

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

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

将poolize maxactive设置为1并尝试。

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

 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; } } 

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

 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 */ } } } 

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

每次建立连接时都要确保在工作完成后关闭它,就像你使用它一样对我有用

 Connection con = null; PreparedStatement pst = con.prepareStatement("...query... "); /* do some stuff */ pst.executeQuery(); pst.close(); con.close(); 

对于那些只进行读取的方法,请尝试@Transactional(readonly=true) 。 也许这适合你。