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.
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.