i wrote tthe below method to insert records using threads, but at run time i receive "[SQLITE_BUSY] The database file is locked (database is locked)" error,and i think could be due to conflict of sqlite statement.
i just want to know i am wusing the executorservice correctly in the "insertRecord" method? is there any other variables shoule have been synchronizedß
code :
public void insertRecord(String nodeID, String lat, String lng, String xmlpath) throws SQLException, ClassNotFoundException {
if (this.isTableExists(this.TABLE_NAME)) {
InsertRun insRun = new InsertRun(this.psInsert, nodeID, lat, lng, xmlpath);
this.executor.execute(insRun);
} else {
Log.e(TAG, "insertRecord", "table: ["+this.TABLE_NAME+"] does not exist");
}
}
public void flush() throws SQLException {
this.psInsert.executeBatch();
this.psInsert.close();
this.connInsert.close();
Log.d(TAG, "insertRecord", "the rest of the records flushed into data base table.");
}
private class InsertRun implements Runnable {
private PreparedStatement psInsert = null;
private String nodeID;
private String lat;
private String lng;
private String xmlPath;
public InsertRun(PreparedStatement psInsert, String nodeID, String lat, String lng, String xmlpath) {
// TODO Auto-generated constructor stub
this.psInsert = psInsert;
this.nodeID = nodeID;
this.lat = lat;
this.lng = lng;
this.xmlPath = xmlpath;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
this.psInsert.setString(1, this.nodeID);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.psInsert.setString(2, this.lat);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.psInsert.setString(3, this.lng);
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
this.psInsert.setString(4, this.xmlPath);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.psInsert.addBatch();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(this) {
if (++batchCnt == SysConsts.BATCH_SIZE) {
try {
this.psInsert.executeBatch();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
batchCnt = 0;
Log.d(TAG, "InsertRun", SysConsts.BATCH_SIZE+" records inserted.");
}
}
}
}
SQLite is not a database suitable for concurrent access. You cannot modify your database concurrently:
Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time, however.
.
When SQLite tries to access a file that is locked by another process, the default behavior is to return SQLITE_BUSY
Read this for details (and simply give up multithreading in your app...)
Additionally, good concurrency design considerations can be difficult to offer without know alot more about the program. Suggest perusing through Java Concurrency in Practice if you plan on writing more multi-threaded applications.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.