CurtTilmes / raku-dbsqlite

SQLite access for Raku
10 stars 4 forks source link

Fix "database is locked" errors in multi-threaded programs #17

Open niner opened 2 years ago

niner commented 2 years ago

If not specified explicitly, a begin will start a deferred transaction, i.e. one that will not attain any locks right away. Instead a read lock is taken when the first select statement is run and this will be upgraded to a write lock on the first insert/update/delete statement. If a concurrent transaction already holds a write lock though, upgrading (or attaining it initially) may fail with SQLITE_BUSY which gets reported as "database is locked".

According to https://stackoverflow.com/questions/6369677/database-is-locked-error-in-sqlite3-with-qt this can be worked around by explicilty starting an immediate transaction. This will attain a write lock immediately. It can still fail with SQLITE_BUSY, but before failing it will wait and try again automatically. This has much better chances of succeeding than the retry on upgrading a lock, because there are no previous results that could be invalidated by that concurrent transaction.

This fixes the test fail on the upcoming Rakudo 2021.12 release.