views:

1422

answers:

3

I am running a SQLite database within a Perl CGI script which is being accessed by DBD::SQLite. This is being run as a straight CGI on Apache.

The DBI connection works fine and selects are able to be run. However, when I attempt to do an insert I get a die with the following error:

DBD::SQLite::st execute failed: unable to open database file(1) at dbdimp.c line 402 at index.cgi line 66

I have tried changing the database file permission to 666 to try to fix this however I am still receiving the error.

Any advice?

+1  A: 

SQLite momentarily locks the entire file when it is doing inserts and updates (there is no record-level locking as such). Are you sure you're freeing the locks?

The SQLite literature recommends that you start a transaction, collect all of your inserts and updates du jour in that transaction, and then commit. This avoids numerous successive file locks, and improves performance.

Robert Harvey
+5  A: 

It looks like the directory needs write permission, the reason is:

SQLite needs to be able to create a journal file in the same directory as the DB, before any modifications can take place. The journal is used to support transaction rollback.

From: seem to need write permission on db's parent directory

Todd Hunter
+1  A: 

Since SQLite locks the entire database file, you may want to use a timeout-based retry mechanism. I was working on pretty much the same problem when I asked this related question.

I ended up writing something similar to Mark Fowler's Attempt that retries if the exception thrown by the sub matches a regular expression, in my case:

qr(already in a transaction|database is locked)i
hillu