zdm has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

According to SQLite documentation, if i set busy_timeout = 0 - handler should wait infinitely while DB is locked.

But, actually, handler immediately dies with message "DBD::SQLite::db do failed: database is locked [for Statement "INSERT INTO session...".

Maybe somebody can help.
  • Comment on SQLite busy_timeout not works as expected

Replies are listed 'Best First'.
Re: SQLite busy_timeout not works as expected
by kcott (Archbishop) on Mar 26, 2014 at 15:19 UTC

    G'day zdm,

    A little more detail on how and where you're setting busy_timeout would probably be helpful in troubleshooting this issue.

    From the current (v3.8.4.1) SQLite documentation, busy_timeout is a PRAGMA. Looking at the PRAGMA documentation, you'll see that these can take effect at different times and this can vary with different releases. So, knowing when you're using this and your SQLite version may be important.

    You only tell us: "set busy_timeout = 0". Is that the command you're using? The documentation for busy_timeout gives the syntax as:

    PRAGMA busy_timeout = milliseconds;

    Are you using set or PRAGMA?

    Also on that page, you'll see:

    "This pragma is an alternative to the sqlite3_busy_timeout() C-language interface which is made available as a pragma for use with language bindings that do not provide direct access to sqlite3_busy_timeout()."

    However, DBD::SQLite does provide such a binding.

    What's the result of querying busy_timeout like this?

    $dbh->sqlite_busy_timeout()

    What's the result of setting busy_timeout like this?

    $dbh->sqlite_busy_timeout(0)

    Documentation for both of those can be found in $dbh->sqlite_busy_timeout() and $dbh->sqlite_busy_timeout($ms).

    -- Ken

Re: SQLite busy_timeout not works as expected
by ww (Archbishop) on Mar 26, 2014 at 15:16 UTC
    For starters, from the online documentation:

    5.0 Writing to a database file

    To write to a database, a process must first acquire a SHARED lock as described above (possibly rolling back incomplete changes if there is a hot journal). After a SHARED lock is obtained, a RESERVED lock must be acquired. The RESERVED lock signals that the process intends to write to the database at some point in the future. Only one process at a time can hold a RESERVED lock. But other processes can continue to read the database while the RESERVED lock is held.

    If the process that wants to write is unable to obtain a RESERVED lock, it must mean that another process already has a RESERVED lock. In that case, the write attempt fails and returns SQLITE_BUSY.

    and

    SQLite uses POSIX advisory locks to implement locking on Unix. On Windows it uses the LockFile(), LockFileEx(), and UnlockFile() system calls. SQLite assumes that these system calls all work as advertised. If that is not the case, then database corruption can result. One should note that POSIX advisory locking is known to be buggy or even unimplemented on many NFS implementations (including recent versions of Mac OS X) and that there are reports of locking problems for network filesystems under Windows. Your best defense is to not use SQLite for files on a network filesystem.

    Questions containing the words "doesn't work" (or their moral equivalent) will usually get a downvote from me unless accompanied by:
    1. code
    2. verbatim error and/or warning messages
    3. a coherent explanation of what "doesn't work actually means.