Subject: | "database is locked" error in DBD::SQLite |
Consider the following program:
#!/usr/bin/perl -w
#
# create test.sqlite with:
# echo 'create table t (c integer);' | sqlite3 test.sqlite
#
use strict;
use DBI;
use DBD::SQLite;
my $d1 = DBI->connect(
'dbi:SQLite:dbname=test.sqlite',
'', '',
{ AutoCommit => 0, RaiseError => 1 }
);
$d1->func(30000, 'busy_timeout');
$d1->do('insert into t (c) values (0)');
sleep(15);
$d1->commit();
$d1->disconnect();
If two copies of this program are run simultaneously, for instance with,
./test & sleep 1 ; ./test
then the second fails with the error "DBD::SQLite::db do failed: database is locked(5) at dbdimp.c line 389 at ./test line 15."
dbdimp.c line 389 is a call to sqlite3_step, which is presumably returning SQLITE_BUSY (code 5). I don't understand why this should happen, given that the busy_timeout function has been called and therefore SQLite should hold off rather than returning immediately with an error code.
In any case it's possible to fix this behaviour by replacing calls to sqlite3_step in dbdimp.c with calls to do_sqlite3_step, defined as follows:
static int do_sqlite3_step(sqlite3_stmt *S) {
int i;
while (SQLITE_BUSY = (i = sqlite3_step(S)))
sleep(1);
return i;
}
-- though the fact that this is necessary suggests that there's a bug in SQLite itself.