Edit report at http://bugs.php.net/bug.php?id=51680&edit=1
ID: 51680 User updated by: ncoesel at dealogic dot nl Reported by: ncoesel at dealogic dot nl Summary: Sqlite returns without waiting for timeout Status: Closed Type: Bug Package: SQLite related Operating System: Linux PHP Version: Irrelevant Assigned To: scottmac New Comment: Sorry for keeping on nagging but this still doesn't fix Bug #51680. Setting a busy_timeout is only part of the solution. @magicaltux: Looping may look unpleasant but that is exactly what every database engine is doing when tables are locked. There is no way around that. Locked is locked. Doing something else may not be a good idea either. If the database is locked it means another process is very busy. Doing something else will take CPU cycles away from that other process and actually prolong the time to wait. Since Sqlite's (file system based) locking mechanism isn't very fine grained the chances of running into a lock when using Sqlite from multiple processes/threads (like PHP does) are very high. Because Sqlite aims to be simplistic it hands parts of handling locked databases to the user. Previous Comments: ------------------------------------------------------------------------ [2010-06-22 03:17:18] fel...@php.net The feature requested in #51295 has been implemented. ------------------------------------------------------------------------ [2010-06-09 14:35:30] magical...@php.net Indeed not a duplicate of 51295, went a bit too fast. Sorry. By the way SQLite has its own view on threads: http://www.sqlite.org/faq.html#q6 Especially I do not like the idea of looping until the query suceeds, especially since it may end sleeping quite a long time. My guess is it would be up to the php part to check for BUSY status and do something else (stream_select?) before retrying (or maybe add an option retry_count to query()/exec() with default=0) Anyway that's just my point of view, I'm reopening this bug and letting scottmac do what he deems appropriate. ------------------------------------------------------------------------ [2010-06-07 09:13:03] ncoesel at dealogic dot nl I'm sorry but you are mistaken. Sqlite_busytimeout may be ignored by Sqlite when two threads of the same process execute a query. This is documented behaviour of Sqlite. See http://www.sqlite.org/c3ref/busy_handler.html in the 4th paragraph. "The presence of a busy handler does not guarantee that it will be invoked when there is lock contention. If SQLite determines that invoking the busy handler could result in a deadlock, it will go ahead and return SQLITE_BUSY or SQLITE_IOERR_BLOCKED instead of invoking the busy handler." I did very thourough research on this and my patch is a way to solve it altough there is always a chance the database may be locked for too long. If that is a problem one might have exceeded Sqlite's capabilities :-) ------------------------------------------------------------------------ [2010-06-07 07:10:06] magical...@php.net This bug is a duplicate of http://bugs.php.net/51295 (which includes a slightly better way of fixing this). ------------------------------------------------------------------------ [2010-04-28 10:49:22] ncoesel at dealogic dot nl Description: ------------ Sqlite has a protection mechanism that prevents firing two (or) more queries from the same process and wait for the database to become available. The typical behaviour is that every now and then (depending on the database load) a query exits immediately with "SQLSTATE[HY000]: General error: 5 database is locked". Setting other busy timeout values doesn't help. I've attached a patch that solves the problem unless the database is locked for a very long time (as usual some error . The patch is created for an older version of PHP. I've checked the latest CVS version and I'm quite sure the patch will still apply. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=51680&edit=1