Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle multiple thread access the sqlite3 with out dblocked error

In my application, background sqlite thread is running... in background thread it fetching data from web service and insert or update data into database. if user insert or delete data from foreground,sometimes i am getting crash it display "sqlite dblocked". but it does not return sqlite busy error.

And i tested thread safe mode

     NSLog(@" sqlite3_threadsafe() = %d", sqlite3_threadsafe());

it display threadsafe is 2.

I want to check if any other db is writing data, if db is writing data.. i want to write data after previous write task is finished.

how to handle these situation..

like image 587
banu Avatar asked Nov 17 '13 10:11

banu


People also ask

Can multiple processes access SQLite?

SQLite allows multiple processes to have the database file open at once, and for multiple processes to read the database at once. When any process wants to write, it must lock the entire database file for the duration of its update.

Is sqlite3 multithreaded?

Overview. SQLite supports three different threading modes: Single-thread. In this mode, all mutexes are disabled and SQLite is unsafe to use in more than a single thread at once.

Is SQLite database thread safe?

Session objects are not thread-safe. In fact, session objects are thread-bound. The {@link SQLiteDatabase} uses a thread-local variable to associate a session with each thread for the use of that thread alone.

Is Python SQLite thread safe?

Is it safe to share an sqlite3 connection between threads? Yes, unless you change the default THREADSAFE option.


3 Answers

You can use lock (such as those enumerated in the Synchronization section of the Threading Programming Guide) or you can use a dedicated serial queue. For example, create a queue:

@property (nonatomic, strong) dispatch_queue_t databaseQueue;

Instantiate it:

self.databaseQueue = dispatch_queue_create("com.company.app.database", 0);

And whenever you want to interact with the database, you can do

dispatch_sync(self.databaseQueue, ^{
    // do your database activity here
});

If you want to simplify your life, the FMDB library has a FMDatabaseQueue object that does much of this for you (as well as greatly simplifying your database interaction in general).

like image 105
Rob Avatar answered Oct 17 '22 01:10

Rob


The thread safe mode prevents crashed when multiple threads access the same connection, but it cannot prevent multiple connections from interfering with each other.

You should use a common lock to protect all database transactions; use either a mutex or the @synchronized directive.

like image 23
CL. Avatar answered Oct 16 '22 23:10

CL.


From the SQLite docs:

Use the SQLITE_THREADSAFE compile-time parameter to selected the threading mode. If no SQLITE_THREADSAFE compile-time parameter is present, then serialized mode is used. This can be made explicit with -DSQLITE_THREADSAFE=1. With -DSQLITE_THREADSAFE=0 the threading mode is single-thread. With -DSQLITE_THREADSAFE=2 the threading mode is multi-thread.

So it seems you have SQLite in multithreaded mode, but not serialised. In this mode, you cannot use the same database connection from different threads, but you will be safe if you open a different connection in each thread.

like image 33
asandroq Avatar answered Oct 17 '22 00:10

asandroq