You can use BEGIN IMMEDIATE or BEGIN EXCLUSIVE depending on the type of lock you'd like.
SQLite BEGIN syntax: http://sqlite.org/lang_transaction.html SQLite locks: http://sqlite.org/lockingv3.html SQLite Busy Handler: http://sqlite.org/capi3ref.html#sqlite3_busy_handler Pat -----Original Message----- From: Russell Leighton [mailto:[EMAIL PROTECTED] Sent: Wednesday, June 07, 2006 8:24 AM To: sqlite-users@sqlite.org Subject: [sqlite] BEGIN and Backup [was Re: [sqlite] Problems with multiple threads?] So, this was very enlightening...I have a simple backup function that I now question is correct. It does: - execute "begin" // lock from writes -copy db file to new file byte by byte - execute "commit" // unlock ...I was thinking that "begin" would lock the file. If I use an flock() [or should it be lockf() ?? ] to bracket the file copy will I be safe? I was hoping to have something more efficient than a table by table copy for backup. Thx [EMAIL PROTECTED] wrote: >As various people search for application and/or SQLite bugs >related to multiple threads and BEGIN, let me try to aid the >effort by better describing exactly what BEGIN does and >suggesting some debugging tricks. > >Realize that BEGIN does not actually create any file locks >or check to see if any file locks already exist, nor >interact in any other way with the filesystem. File locks >are only created by SELECT, UPDATE, INSERT, and DELETE >statements. (OK, also CREATE and DROP statements, but >let's ignore those for now for simplicity. Presumably >the schema is fixed at the point where the problems are >occuring.) All BEGIN does is to set a flag that says >"do not automatically perform a COMMIT after each write >to the database". This is the autoCommit flag that I >mentioned in a prior email. autoCommit is a boolean >member of the sqlite3 structure. A lock is acquired >at the beginning of each UPDATE, INSERT, or DELETE >if it does not already exists. After each UPDATE, >INSERT, or DELETE, sqlite checks the value of the >autoCommit flag, and if it is true it automatically >does a COMMIT. A read-lock is acquired before each >SELECT if it does not already exists, and after the >SELECT is done, the read-lock is dropped if autoCommit >is true. > >So the BEGIN instruction does not do anything with the >filesystem. It does not interact in any way with the >operating system or with other database connections. >All BEGIN does is clear the autoCommit flag. So it is >hard to imagine how having other threads could possibly >effect its behavior. > >At any time, you can determine the value of the autoCommit >flag using the sqlite3_get_autocommit() API. See > > http://www.sqlite.org/capi3ref.html#sqlite3_get_autocommit > >I suggest that people who are getting back unexpected >"cannot start a transaction within a transaction" errors >should use the sqlite3_get_autocommit() API in some printf()s >to trace the status of the autocommit flag within their >application. Prior to running BEGIN, it should always >be the case that sqlite3_get_autocommit() returns TRUE. >If sqlite3_get_autocommit() returns FALSE, then the BEGIN >that follows will give the "cannot start..." error. > >I suspect what is happening is that some prior COMMIT >or ROLLBACK is not setting the autoCommit flag back to >TRUE. This might be because the COMMIT or ROLLBACK >failed. Or, there could be some kind of bug in SQLite >that is causing the autoCommit flag to not be set >correctly. I suspect the former, but am open to evidence >pointing to the latter. It might be useful to use the >sqlite3_get_autocommit() function to print out the value >of the autoCommit flag after each COMMIT and ROLLBACK is >executed. This might help to isolate the problem. > >-- >D. Richard Hipp <[EMAIL PROTECTED]> > > >