2012-12-15 14 views
16
साथ लॉक हो गया है

अगर मैं अपने वेब अनुप्रयोग के खिलाफ एक से अधिक थ्रेड चलाने मैं:हो रही है [SQLITE_BUSY] डेटाबेस फ़ाइल का चयन करें बयान

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> 

सेटअप है: जावा 1.6, बिलाव 7.0.34, स्प्रिंग 3.2, हाइबरनेट 3.6.9 और 3.7.2 sqlite3

सादर रोजर

+0

संभावित डुप्लिकेट [SQLITE \ _BUSY डेटाबेस फ़ाइल लॉक है (डेटाबेस लॉक है) विकेट में] (http://stackoverflow.com/questions/8559623/sqlite-busy-the-database-file-is-locked- डेटाबेस-इन-लॉक-इन-विकेट) – Stephan

उत्तर

15

कुछ googling के बाद मुझे पता चला कि SQLite से कनेक्ट करते समय एकाधिक कनेक्शन का उपयोग करना एक बुरा अभ्यास है। देखें

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

1 करने के लिए अपने poolsize maxactive निर्धारित करें और बाहर की कोशिश करो।

+0

हां जो काम करता है। लेकिन मुझे अभी भी समझ में नहीं आता कि फाइल लॉक क्यों है, हालांकि केवल चयन कथन निष्पादित किए जाते हैं। – rogergl

+0

@rogergl: SQLiteOpenHelper # getReadableDatabase() के साथ कनेक्शन प्राप्त करने का प्रयास करें। लिंक: http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html – sorencito

0

उन विधियों के लिए @Transactional(readonly=true) आज़माएं जो केवल पढ़ते हैं। शायद यह आपके लिए काम करता है।

+0

इससे – rogergl

+0

ठीक नहीं है, मेरा नया उत्तर देखें। – sorencito

+0

यह इस स्थिति की घटना को कम करने के लिए कई चरणों में से एक के रूप में SQLite दस्तावेज़ों के भीतर भी अनुशंसा की जाती है। पहला कदम यह सुनिश्चित करना होगा कि सब कुछ बंद हो। यह भी जांचना चाहिए कि डेटाबेस थ्रेडिंग का समर्थन करता है (डिफ़ॉल्ट चालू है) FULLMUTEX – oden

9

आपके आवेदन के साथ केवल एक कनेक्शन होना चाहिए। आप इसे सुनिश्चित करने के लिए उपयोग कर सकते हैं।

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

भी ध्यान रखें कि इस करता है, तो आप गलती से अपने कनेक्शन बंद करने के लिए भूल जाते हैं हो सकता है:

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

पहले डेटाबेस कनेक्शन अच्छी तरह से काम कर सकते हैं एक बार सर्वर शुरू कर दिया है, बाद में प्रश्नों नहीं हो सकता, पर निर्भर करता है कनेक्शन पूल कैसे कॉन्फ़िगर किया गया है।

संबंधित मुद्दे