Reputation: 20344
After enabling Write-Ahead Log mode for a volatile SQLite3 database (PRAGMA journal_mode = WAL
), my concurrency tests began raising this error. I discovered that this happens when the Python process is forked and a connection is left open to a database in WAL mode. Any subsequent execute()
on that database, even with a new connection, throws this 'locking protocol'
exception.
Disabling WAL mode (PRAGMA journal_mode = DELETE
) makes the problem disappear, and neither does any 'database is locked'
error occur either. The 'locking protocol'
exception seems reflect the SQLITE_PROTOCOL code underneath which is documented as:
The SQLITE_PROTOCOL result code indicates a problem with the file locking protocol used by SQLite.
I'm using Python 2.7.10 on Mac OS X 10.12.6 Sierra. I think the problem is in Python's sqlite3
module and how it deals with being forked, rather than an issue in SQLite3 itself. I know now how to work around the issue but as per the main question, what is the root cause of this issue?
P.S. - I'm not using any threads and am forking by spawning a daemon child.
Upvotes: 4
Views: 4518
Reputation: 20344
SQLite3 is obviously not thread-safe as per the FAQ but, as CL pointed out in the comments to my question, there is a line relating to forking there:
Under Unix, you should not carry an open SQLite database across a fork() system call into the child process.
This doesn't exactly provide an answer as to the cause, however it does point out a solution: close ALL SQLite connections in (or before) a fork()
process! Holding onto forked connections prevents new connections from taking place across any process!
Upvotes: 3