|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-02-21 18:35 UTC] rjohnson at intepro dot us
Description: ------------ When executing 2 separate processes that insert or update a SQLite3 database, PDO allows both to begin a transaction rather than indicating that another transaction has locked the database. This causes deadlock. Using SQLite2 we would issue a BEGIN and catch a SQLITE_BUSY, then usleep and try again. This worked flawlessly. Reproduce code: --------------- http://beacon.intepro.us/pdoSqliteBug.html Expected result: ---------------- We run this code from 2 tabs in Firefox with name=0 and name=1 passed as $_GET params. The sleep(1) allows us enough time to execute both processes simultaneously. The beginTransaction in the 2nd script should detect that SQLite is busy (the 1st transaction has a lock on the file), the code should sleep for .25 of a second and try again until the first process is done, then the second should complete. Both processes should complete in roughly 20 seconds. Actual result: -------------- Both scripts run indefinitely. If we stop the second process, the first will complete. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 28 12:00:01 2025 UTC |
I believe I found a fix for this (or at least a workaround). It looks like the real problem was with PDO::prepare(). Prepared statements must be prepared prior to calling PDO::beginTransaction() Right now this is working for us in test: 1. Create the SQLite3 PDO connection 2. Prepare any statements necessary 3. Set a loop test variable and start loop 4. Start try{} block 5. Call beginTransaction() to get out of autocommit mode 6. Attempt to execute prepared statement -> could throw PDOException "DATABASE IS LOCKED", skip to step 9 7. Call PDO::commit() to commit changes 8. Set loop test variable to false and/or break loop 9. Catch "DATABASE IS LOCKED" PDOException, sleep for some period of time and reiterate the loop (Go to step 3) If this passes our tests, I'll make a note of it in the online manual.