Reputation: 43
Many people said that SQLiteDatabase is thread-safe,but ,when i ran some simple tests with setup like this:
private class MyRunnable implements Runnable{
@Override
public void run() {
for(int i = 0 ;i < 100 ; i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Cursor cursor = database.query(true,"testdb",new String[]{"num"},"id=?",
new String[]{"1"},null,null,null,null);
cursor.moveToFirst();
int original = cursor.getInt(0);
ContentValues values = new ContentValues();
values.put("num",++original);
database.update("testdb",values,"id=?",new String[]{"1"});
}
}
}
MyRunnable runnable1 = new MyRunnable();
MyRunnable runnable2 = new MyRunnable();
new Thread(runnable1).start();
new Thread(runnable2).start();
In MyRunnable ,there is a loop that runs 100 times. Each time, the num field will add by 1 and the num's initial value is 0. we can see that the above code's expected result is 200,but i only get 197.
so does that mean SQLiteDatabase is not thread-safe?
Upvotes: 1
Views: 269
Reputation: 367
No, the way you are handling the data is just not thread-safe. You could use an atomic SQL-query like:
UPDATE table SET num = num + 1
Instead of retrieving the data in your application code, modifying it and storing it back.
SQLite being threadsafe means that you can safely use all SQLite functions in multiple threads at once, it does not mean the database gets locked automatically depending on what you are doing. If your thread gets interrupted anywhere between the query() call and the update() call, returning to the thread at that point will mean the data you retrieved earlier is no longer up to date.
Upvotes: 4