2011-02-25 11 views
9

मैं SQLite डेटाबेस और वसंत का उपयोग करने वाले एक एप्लिकेशन को विकसित कर रहा हूं। मैं समस्या है जब एक से अधिक थ्रेड डेटाबेस को संशोधित करने की कोशिश - मैं कोई त्रुटि मिलती है:वसंत + बहु-थ्रेडेड अनुप्रयोग में SQLite

'डेटाबेस फ़ाइल लॉक है'

मैं एक ही डेटा स्रोत कॉन्फ़िगर किया:

<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" 
     destroy-method="close" lazy-init="true"> 
    <property name="driverClassName" value="org.sqlite.JDBC" /> 
    <property name="url" value="jdbc:sqlite:sample.db" /> 
    <property name="initialSize" value="2" /> 
    <property name="maxActive" value="20" /> 
    <property name="maxIdle" value="5" /> 
    <property name="poolPreparedStatements" value="true" /> 
</bean> 

और प्रत्येक सूत्र में मैं JdbcDaoSupport का एक अलग इंस्टेंस कि डेटाबेस के लिए एक डालने करता है:

getJdbcTemplate().update(
    "insert into counts values(15)" 
); 

समारोह है कि डेटाबेस अद्यतन करता है transac है tional (मैंने सभी अलगाव स्तरों की कोशिश की है, प्रत्येक मामले में मुझे एक ही त्रुटि मिलती है)।

अन्य डेटाबेस (MySQL) का उपयोग करते समय, वही कोड ठीक काम करता है।

मैं इसे कैसे हल कर सकता हूं (मेरे कोड में 'मैन्युअल' सिंक्रनाइज़ेशन जोड़ने के बिना)?

+0

आप अपने ऐप की कितनी समवर्ती उम्मीद करते हैं? याद रखें कि, डिज़ाइन द्वारा, SQLite को MySQL के लिए fopen() और -not- के प्रतिस्थापन का इरादा नहीं है। यदि आपको आरडीबीएमएस की आवश्यकता है जिसे समवर्ती डेटा एक्सेस के लिए 2PL या MVCC को संभालने के लिए डिज़ाइन किया गया है, तो आप एक और आरडीबीएमएस पर विचार करना चाहेंगे। MySQL, HSQLDB, या डर्बी सभी में वास्तविक क्लाइंट-सर्वर समर्थन है। – scottb

उत्तर

1

उम्मीद है कि मेरे पास आपके लिए सही उत्तर है - Berkeley DB और SQL API। पिछले साल बर्कले डीबी ने एसक्यूएलएट की एसक्यूएल परत के साथ अपने स्टोरेज इंजन को संयुक्त किया, जो एक संयुक्त उत्पाद प्रदान करता है जो दोनों दुनिया के सर्वश्रेष्ठ प्रदान करता है। बर्कले डीबी की समेकन, प्रदर्शन, स्केलेबिलिटी और विश्वसनीयता के साथ, SQLite के उपयोग की सर्वव्यापीता और आसानी।

यह आपकी समस्या का समाधान क्यों करेगा? चूंकि बर्कले डीबी पूरी तरह से SQLite संगत है, लेकिन एक अलग, अधिक समवर्ती लॉक प्रबंधक लागू करता है। इसका मतलब है कि बर्कले डीबी में आप एक ही समय में डेटाबेस तक पहुंचने वाले कई अपडेट थ्रेड प्राप्त कर सकते हैं। माइक ओवेन्स ("SQLite के लिए परिभाषित मार्गदर्शिका" के लेखक) के लेखक, Technical & Performance Evaluation और Benefits and Differences द्वारा लिखे गए विषय पर कुछ रोचक सफेद कागजात हैं।

अस्वीकरण: मैं बर्कले डीबी के लिए उत्पाद प्रबंधक हूं, इसलिए मैं थोड़ा पक्षपातपूर्ण हूं। हालांकि, आप पाएंगे कि बर्कले डीबी एसक्यूएल एपीआई ठीक आपके द्वारा उठाए गए मुद्दे को हल करता है - SQLite में समवर्ती पढ़ने/लिखने के संचालन को कैसे अनुमति दें।

+0

बर्कले डीबी के लिए लाइसेंसिंग क्या है? क्या मैं बिना किसी लागत के वाणिज्यिक एप्लिकेशन के साथ इसे वितरित कर सकता हूं? –

+0

आप यहां बर्कले डीबी लाइसेंस पा सकते हैं: http://bit.ly/g7h1mf। असल में यह एक दोहरी लाइसेंस है। ओपन सोर्स प्रोजेक्ट्स के लिए ओपन सोर्स यूज। बंद स्रोत अनुप्रयोगों के लिए वाणिज्यिक लाइसेंस या ओरेकल समर्थन प्राप्त करने के लिए। – dsegleau

+0

एक और विकल्प के रूप में, एचएसक्यूएलडीबी (http://www.hsqldb.org) मुफ़्त है, जीपीएल जैसी लाइसेंस के तहत उपलब्ध है, अब संस्करण 2.3.0 में है और लगातार 10 वर्षों से विकसित किया गया है। इसमें असली क्लाइंट-सर्वर (या स्टैंड-अलोन) समर्थन है, एक परिपक्व जेडीबीसी 4.1 ड्राइवर, एएनएसआई एसक्यूएल: 2008 के लिए लगभग पूर्ण समर्थन है, और 2PL और एमवीसीसी मॉडल दोनों के माध्यम से एकाधिक पहुंच का समर्थन करता है। – scottb

3

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

मुझे लगता है कि निम्नलिखित की तरह कुछ होगा ...

<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" lazy-init="true"> 
    <property name="driverClassName" value="org.sqlite.JDBC" /> 
    <property name="url" value="jdbc:sqlite:sample.db" /> < 
    <property name="initialSize" value="1" /> 
    <property name="maxActive" value="1" /> 
    <property name="maxIdle" value="1" /> 
    <property name="poolPreparedStatements" value="true" /> 
</bean> 
2

बस पकड़ने और पुनः प्रयास करें। यह सामान्य SQLite व्यवहार है।

[संपादित करें]] SQLite खुद को पुनः प्रयास करेगा; यह त्रुटि फेंक दी जाती है अगर रीट्री एक निश्चित अवधि के भीतर काम नहीं करते हैं। आप विभिन्न तरीकों से अवधि बढ़ा सकते हैं: http://www.sqlite.org/pragma.html#pragma_busy_timeouthttp://www.sqlite.org/c3ref/busy_timeout.html

0

वसंत के साथ, आप SingleConnectionDataSource का लाभ उठा सकते हैं। मेरे उपयोग के लिए (300+ आवेषण/दूसरा), यह ठीक काम करता है।

@Bean 
public DataSource jdbcDataSource() { 
    SingleConnectionDataSource ds = new SingleConnectionDataSource(); 
    ds.setDriverClassName("org.sqlite.JDBC"); 
    ds.setUrl("jdbc:sqlite:stats.db"); 
    return ds; 
} 
+0

सिंगलकनेक्शनडेटा स्रोत दस्तावेज से उद्धरण "जाहिर है, यह बहु-थ्रेडिंग सक्षम नहीं है।" – PhoneixS

+0

@PhoneixS वास्तविक प्रश्न नहीं हैं, नहीं, लेकिन वसंत सिंक्रनाइज़ेशन को तब तक संभालती है जब तक आप वसंत जेडीबीसी कक्षाओं जैसे जेडीबीसी टेम्पलेट का उपयोग करते हैं। – wmarbut