2012-12-15 16 views
16

Se corro più thread contro la mia web app ottengo:Operazioni [SQLITE_BUSY] file di database è bloccato con 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) 

so che solo un thread può scrivere in un database SQLite, ma io sono solo leggendo dal database. Allora, perché ricevo questo messaggio di errore?

BTW: Il mio pool di connessioni si presenta così:

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

La messa a punto è: Java 1.6, Tomcat 7.0.34, Primavera 3.2, Hibernate 3.6.9 e 3.7.2 sqlite3

Saluti Roger

+0

Possibile duplicato di [SQLITE \ _BUSY Il file di database è bloccato (il database è bloccato) in wicket] (http://stackoverflow.com/questions/8559623/sqlite-busy-the-database-file-is-locked- database-is-locked-in-wicket) – Stephan

risposta

15

Dopo aver cercato su google ho scoperto che è una cattiva pratica utilizzare più connessioni durante la connessione a SQLite. Vedi

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

impostare il proprio maxActive poolsize a 1 e provare.

+0

Sì, funziona. Ma ancora non capisco perché il file è bloccato anche se vengono eseguite solo le istruzioni selezionate. – rogergl

+0

@rogergl: prova ad ottenere una connessione con SQLiteOpenHelper # getReadableDatabase(). Link: http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html – sorencito

0

Prova @Transactional(readonly=true) per quei metodi che solo si legge. Forse funziona per te.

+0

Questo non aiuta – rogergl

+0

Ok, guarda la mia nuova risposta. – sorencito

+0

Questo è anche raccomandato all'interno della documentazione SQLite come una delle varie fasi per ridurre il verificarsi di questa situazione. Il primo passo sarebbe garantire che tutto sia chiuso. Inoltre, è necessario verificare che il database supporti il ​​threading (l'impostazione predefinita è attivata) FULLMUTEX – oden

9

Ci dovrebbe essere solo una connessione con la vostra applicazione. è possibile utilizzare questo per garantire.

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

Si noti inoltre che questo può accadere se ci si dimentica accidentalmente chiudere il tuo collegamento:

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

Mentre la prima connessione al database può funzionare bene una volta avviato il server, query successive non possono, a seconda come è configurato il pool di connessioni.

Problemi correlati