开发者

sqlite db remains locked/unaccessible

开发者 https://www.devze.com 2023-04-12 19:25 出处:网络
I have a problem with an sqlite3 db which remains locked/unaccessible after a certain access. Behaviour occurs so far on Ubuntu 10.4 and on custom (OpenEmbedded) Linux.

I have a problem with an sqlite3 db which remains locked/unaccessible after a certain access.

Behaviour occurs so far on Ubuntu 10.4 and on custom (OpenEmbedded) Linux. The sqlite version is 3.7.7.1). Db is a local file.

One C++-applications accesses the db periodically (5s). Each time several insert statements are done wrapped in a deferred transaction. This happens in one thread only. The connection to the db is held over the whole lifetime of the application. The statements used are also persistent and reused via sqlite3_res开发者_StackOverflowet. sqlite_threadsafe is set to 1 (serialized), journaling is set to WAL.

Then I open in parellel the sqlite db with the sqlite command line tool. I enter BEGIN IMMEDIATE;, wait >5s, and commit with END;.

after this the db access of the application fails: the BEGIN TRANSACTION returns return code 1 ("SQL error or missing database"). If I execute an ROLLBACK TRANSACTION right before the begin, just to be sure there is not already an active transaction, it fails with return code 5 ("The database file is locked").

Has anyone an idea how to approach this problem or has an idea what may cause it?

EDIT: There is a workaround: If the described error occures, I close and reopen the db connection. This fixes the problem, but I'm currently at a loss at to why this is so.


Sqlite is a server less database. As far as I know it does not support concurrent access from multiple source by design. You are trying to access the same backing file from both your application and the command tool - so you attempt to perform concurrent access. This is why it is failing.


SQLite connections should only be used from a single thread, as among other things they contain mutexes that are used to ensure correct concurrent access. (Be aware that SQLite also only ever supports a single updating thread at once anyway, and with no concurrent reads at the time; that's a limitation of being a server-less DB.)

Luckily, SQLite connections are relatively cheap when they're not doing anything and the cost of things like cached prepared statements is actually fairly small; open up as many as you need.

[EDIT]: Moreover, this would explain closing and reopening the connection works: it builds the connection in the new thread (and finalizes all the locks etc. in the old one).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号