2012-12-15 3 views
16

Wenn ich mehrere Threads gegen meinen Web-app laufen erhalte ich:Erste [SQLITE_BUSY] Datenbankdatei wird mit select-Anweisungen gesperrt

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) 

Ich weiß, dass nur ein Thread zu einer SQLite-Datenbank schreiben kann, aber ich bin nur aus der Datenbank lesen. Also, warum bekomme ich diese Fehlermeldung?

BTW: Meine Verbindung Pool sieht wie folgt aus:

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

Das Setup ist: Java 1.6, Tomcat 7.0.34, Frühling 3.2, Hibernate 3.6.9 und 3.7.2 sqlite3

Grüße Roger

+0

Mögliches Duplikat von [SQLITE \ _BUSY Die Datenbankdatei ist gesperrt (Datenbank ist gesperrt) in Wicket] (http://stackoverflow.com/questions/8559623/sqlite-busy-the-database-file-is-locked- database-is-locked-in-wicket) – Stephan

Antwort

15

Nach einigem googeln habe ich festgestellt, dass es eine schlechte Übung ist, mehrere Verbindungen zu verwenden, wenn man sich mit SQLite verbindet. Siehe

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

Stellen Sie Ihren Poolsize maxActive 1 und auszuprobieren.

+0

Ja, das funktioniert. Aber ich verstehe immer noch nicht, warum die Datei gesperrt ist, obwohl nur Select-Anweisungen ausgeführt werden. – rogergl

+0

@rogergl: Versuchen Sie, eine Verbindung mit SQLiteOpenHelper # getReadableDatabase() zu bekommen. Link: http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html – sorencito

0

Versuchen Sie @Transactional(readonly=true) für die Methoden, die nur liest. Vielleicht funktioniert das für dich.

+0

Das hilft nicht – rogergl

+0

Ok, sehe meine neue Antwort. – sorencito

+0

Dies wird auch in der SQLite-Dokumentation als einer von mehreren Schritten empfohlen, um das Auftreten dieser Situation zu reduzieren. Der erste Schritt wäre, sicherzustellen, dass alles geschlossen ist. Außerdem sollte überprüft werden, ob die Datenbank Threading unterstützt (Standard ist on) FULLMUTEX – oden

9

Es sollte nur EINE Verbindung mit Ihrer Anwendung geben. können Sie dies verwenden, um sicherzustellen.

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

Beachten Sie auch, dass dies passieren kann, wenn Sie versehentlich Ihre Verbindung vergessen zu schließen:

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

Während die erste Datenbankverbindung kann gut funktionieren, wenn der Server gestartet wird, können nachfolgende Abfragen nicht, je nachdem, wie der Verbindungspool konfiguriert ist

Verwandte Themen