Получение файла базы данных [SQLITE_BUSY] заблокировано с помощью операторов 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, но я только читаю из базы данных. Так почему я получаю это сообщение об ошибке?
BTW: Мой пул подключений выглядит следующим образом:
<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>
Настройка: Java 1.6, Tomcat 7.0.34, Spring 3.2, Hibernate 3.6.9 и sqlite3 3.7.2
Отношения Роджер
Ответы
Ответ 1
После некоторых поисковых запросов я обнаружил, что при подключении к SQLite плохо использовать разные соединения. См
http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking
Настройте максимальную мощность пула на 1 и попробуйте.
Ответ 2
Должно быть только одно соединение с вашим приложением.
вы можете использовать это для обеспечения.
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;
}
}
Ответ 3
Обратите внимание, что это может произойти, если вы случайно забыли закрыть свое соединение:
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 */
}
}
}
В то время как первое соединение с базой данных может работать хорошо после запуска сервера, последующие запросы могут не совпадать, в зависимости от того, как настроен пул соединений.
Ответ 4
Каждый раз, когда вы устанавливаете соединение, обязательно закройте его после завершения работы. Он работал для меня, как если бы вы использовали
Connection con = null;
PreparedStatement pst = con.prepareStatement("...query... ");
/*
do some stuff
*/
pst.executeQuery();
pst.close();
con.close();
Ответ 5
Для меня проблема заключалась в том, что я открывал слишком много сеансов. Поэтому я сделал поле сеанса в своем классе DAO static
Ответ 6
Попробуйте @Transactional(readonly=true)
для тех методов, которые только читают. Возможно, это работает для вас.