How to handle the sqlite3.OperationalError: database is locked

328 Views Asked by At

I used Python code that followed the pattern:

database = sqlite3.connect("path to database")
for job in range(1000):
    for row in database.execute("SELECT something"):
        database.execute("UPDATE something for the row")
        database.commit()

The application is a long running process, it queries some jobs from the database, executes each job (makes an HTTP request) one by one. The "SELECT something" returns a single row by design (however it may return a batch of rows), then for each row the application updates the database writing into the row the result of the job.

This works if I run this application in a single process, but I need to parallelize execution, so I'm running several processes with the same code. As the result I started to get sqlite3.OperationalError exceptions with the description "database is locked". I didn't handle this exception, so the processes were crashing, and I was restarting them manually.

Now I wish to avoid crashes, and in case of the database lock I'm catching the exception. My goal is to discard the result of the current job and continue with the next one, so I changed the code:

database = sqlite3.connect("path to database")
for job in range(1000):
    for row in database.execute("SELECT something"):
        try:
            # process row
            database.execute("UPDATE something for the row")
            database.commit()
        except sqlite3.OperationalError as e:
            # wait for some time to allow other processes to complete the transaction

Now I'm getting a deadlock as both processes cannot proceed with their queries, both discard the results, make queries again and always get the exception. If I kill one of two processes, the other can continue processing the jobs successfully. My goal is to drop the connection state in case of catching the sqlite3.OperationalError. Closing/reopening the connection doesn't help as I fail to open the locked database after closing it. Is there an API that allows to unlock the database without closing?

0

There are 0 best solutions below