On Apr 6, 2009, at 5:02 AM, Alexander Batyrshin wrote:

> Hello all,
> I have found that busy_timeout doesn work in this case:
>
> ------- 
> %< 
> --------------------------------------------------------------------------------
> #include <stdio.h>
> #include <sqlite3.h>
>
>
> int check_error (int rc, char *zErrMsg)
> {
>  if( rc!=SQLITE_OK ){
>    fprintf(stderr, "SQL error: %s\n", zErrMsg);
>    sqlite3_free(zErrMsg);
>  }
> }
>
> int main(int argc, char **argv){
>  sqlite3 *db, *db2;
>  char *zErrMsg = 0;
>  int rc;
>
>  rc = sqlite3_open("test.db", &db);
>  rc = sqlite3_open("test.db", &db2);
>
>  printf("db1 start trans\n");
>  rc = sqlite3_exec(db, "BEGIN TRANSACTION" , NULL, NULL, &zErrMsg);
>  check_error(rc, zErrMsg);
>
>  printf("db1 insert\n");
>  rc = sqlite3_exec(db, "INSERT INTO Blah VALUES ( 1, 'Test1' )" ,
> NULL, NULL, &zErrMsg);
>  check_error(rc, zErrMsg);
>
>
>  sqlite3_busy_timeout(db2, 30000);
>
>  printf("db2 start trans\n");
>  rc = sqlite3_exec(db2, "BEGIN TRANSACTION" , NULL, NULL, &zErrMsg);
>  check_error(rc, zErrMsg);
>
>  /* SQLITE should wait for 3 second before returning error, but it  
> doesn't  */
>  printf("db2 insert\n");
>  rc = sqlite3_exec(db2, "INSERT INTO Blah VALUES ( 1, 'Test1' )" ,
> NULL, NULL, &zErrMsg);
>  check_error(rc, zErrMsg);
>
>  sqlite3_close(db);
>  return 0;
> }
>
> ------- 
> %< 
> --------------------------------------------------------------------------------
>
> Most interesting thing that If you try to INSERT in db2 WITHOUT
> transaction busy_timeout() will work correctly.

Or if you execute any SELECT statement using db2 before the
BEGIN TRANSACTION statement.

sqlite3_exec() is implemented using the standard prepare_v2()/
step()/finalize() APIs. While prepare()ing the INSERT statement executed
by db2, SQLite obtains a SHARED (read) lock on the database file in  
order
to read the database schema. Because there is a transaction open,
the SHARED lock is not released when sqlite3_prepare() returns. At
this point db2 has a SHARED lock and db1 has RESERVED. When  
sqlite3_step()
is called, db2 attempts to upgrade to a RESERVED lock. You then have
the situation described in the 4th paragraph of the documentation here:

   http://www.sqlite.org/c3ref/busy_handler.html

You could argue that SQLite should drop the SHARED lock on the database
when the call to sqlite3_prepare() on db2 returns in this case.

Dan.



>
> --
> Alexander Batyrshin aka bash
> Biomechanical Artificial Sabotage Humanoid
> _______________________________________________
> sqlite-users mailing list
> [email protected]
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to