मैंने एक जावा एप्लिकेशन लिखा है जो कई धागे से SQLite डेटाबेस में घटनाओं को स्पोरैडिक रूप से लॉग करता है। मैंने देखा है कि मैं एक ही समय में छोटी संख्या में घटनाओं को उत्पन्न करके अपेक्षाकृत आसानी से SQLite की "डेटाबेस लॉक" त्रुटियों को ट्रिगर कर सकता हूं। इसने मुझे एक परीक्षण कार्यक्रम लिखने के लिए प्रेरित किया जो सबसे खराब केस व्यवहार की नकल करता है और मुझे आश्चर्य हुआ कि ऐसा लगता है कि SQLite इस उपयोग के मामले में कितना खराब प्रदर्शन करता है। नीचे पोस्ट किया गया कोड बस डेटाबेस पर पांच रिकॉर्ड जोड़ता है, पहले अनुक्रमिक रूप से "नियंत्रण" मान प्राप्त करने के लिए। फिर एक ही पांच रिकॉर्ड समवर्ती रूप से जोड़े जाते हैं।एक बहुप्रचारित जावा एप्लिकेशन में SQLite
[java] Sequential DB access:
[java] SQL Insert completed: 132
[java] SQL Insert completed: 133
[java] SQL Insert completed: 151
[java] SQL Insert completed: 134
[java] SQL Insert completed: 125
[java] Concurrent DB access:
[java] SQL Insert completed: 116
[java] SQL Insert completed: 1117
[java] SQL Insert completed: 2119
[java] SQL Insert failed: 3001 SQLException: java.sql.SQLException: database locked
[java] SQL Insert completed: 3136
5 रिकॉर्ड क्रमिक रूप से लगभग 750 मिलीसेकेंड लेता सम्मिलित करना, मैं समवर्ती आवेषण समय का लगभग एक ही राशि लेने के लिए उम्मीद करेंगे:
import java.sql.*;
public class Main {
public static void main(String[] args) throws Exception {
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db");
Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists people");
stat.executeUpdate("create table people (name, occupation)");
conn.close();
SqlTask tasks[] = {
new SqlTask("Gandhi", "politics"),
new SqlTask("Turing", "computers"),
new SqlTask("Picaso", "artist"),
new SqlTask("shakespeare", "writer"),
new SqlTask("tesla", "inventor"),
};
System.out.println("Sequential DB access:");
Thread threads[] = new Thread[tasks.length];
for(int i = 0; i < tasks.length; i++)
threads[i] = new Thread(tasks[i]);
for(int i = 0; i < tasks.length; i++) {
threads[i].start();
threads[i].join();
}
System.out.println("Concurrent DB access:");
for(int i = 0; i < tasks.length; i++)
threads[i] = new Thread(tasks[i]);
for(int i = 0; i < tasks.length; i++)
threads[i].start();
for(int i = 0; i < tasks.length; i++)
threads[i].join();
}
private static class SqlTask implements Runnable {
String name, occupation;
public SqlTask(String name, String occupation) {
this.name = name;
this.occupation = occupation;
}
public void run() {
Connection conn = null;
PreparedStatement prep = null;
long startTime = System.currentTimeMillis();
try {
try {
conn = DriverManager.getConnection("jdbc:sqlite:test.db");
prep = conn.prepareStatement("insert into people values (?, ?)");
prep.setString(1, name);
prep.setString(2, occupation);
prep.executeUpdate();
long duration = System.currentTimeMillis() - startTime;
System.out.println(" SQL Insert completed: " + duration);
}
finally {
if (prep != null) prep.close();
if (conn != null) conn.close();
}
}
catch(SQLException e) {
long duration = System.currentTimeMillis() - startTime;
System.out.print(" SQL Insert failed: " + duration);
System.out.println(" SQLException: " + e);
}
}
}
}
यहाँ जब मैं इस जावा कोड चलाने उत्पादन होता है। लेकिन आप देख सकते हैं कि एक 3 सेकंड टाइमआउट दिया गया है, वे भी खत्म नहीं करते हैं। मैंने एसक्यूएल के मूल लाइब्रेरी कॉल का उपयोग करके सी में एक समान परीक्षण कार्यक्रम भी लिखा था और समवर्ती आवेषणों के साथ-साथ एक साथ एक साथ आवेषण समाप्त हो गया था। तो समस्या मेरी जावा पुस्तकालय के साथ है।
Sequential DB access:
SQL Insert completed: 126 milliseconds
SQL Insert completed: 126 milliseconds
SQL Insert completed: 126 milliseconds
SQL Insert completed: 125 milliseconds
SQL Insert completed: 126 milliseconds
Concurrent DB access:
SQL Insert completed: 117 milliseconds
SQL Insert completed: 294 milliseconds
SQL Insert completed: 461 milliseconds
SQL Insert completed: 662 milliseconds
SQL Insert completed: 862 milliseconds
मैं दो अलग अलग JDBC ड्राइवर (http://www.zentus.com/sqlitejdbc और http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC), और sqlite4java आवरण के साथ इस कोड की कोशिश की:
यहाँ जब मैं सी संस्करण को चलाने के उत्पादन होता है। हर बार परिणाम समान थे। क्या वहां कोई भी जावा के लिए SQLite लाइब्रेरी के बारे में जानता है जिसके पास यह व्यवहार नहीं है?
इसलिए यदि समस्या की जड़ फाइल सिस्टम ताले है, तो मेरा सी कोड जितना तेज़ चलता है? – jlunavtgrad
hurray! उसी जेडीबीसी कनेक्शन का उपयोग करके पूरी तरह से समस्या हल हो गई। अब मैं अपने सी कोड से बेहतर या बराबर प्रदर्शन देख रहा हूं। मैंने कल उपरोक्त जावा कार्यक्रम के साथ यह कोशिश की थी, लेकिन अब मुझे एहसास हुआ कि मैं प्रत्येक सम्मिलन के लिए एक नए के साथ अपने कनेक्शन को ओवरराइट कर रहा था। – jlunavtgrad
यह भी देखें: http://stackoverflow.com/questions/24513576/opening-database-connection-with-the-sqlite-open-nomutex-flag-in-java – Stephan