Neil C. Obremski
Neil C. Obremski

Reputation: 20344

Causes of sqlite3.OperationalError "locking protocol" exception?

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

Answers (1)

Neil C. Obremski
Neil C. Obremski

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

Related Questions