使用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)
。 也许这适合你。