On May 5, 2010, at 8:32 PM, myomancer wrote:

> Dear Users
>
> I've spent hours reading various web-based documents, examined lots of
> code snippets, written some code of my own, but I still patently do
> not understand SQLite locks.

4th paragraph of this page (The presence of a busy...) describes the
condition your program is hitting:

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




>
> My misunderstanding is probably best illustrated with a concrete
> example written in C.
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <sqlite3.h>
>
> int main()
> {
>       sqlite3 *db;
>       int error;
>        sqlite3_stmt *res;
>       int count;
>       char *sqlite_query;
>
>       error = sqlite3_open_v2("simple.db3", &db, SQLITE_OPEN_READWRITE, 0);
>       if(error)
>       {
>               fprintf(stderr, "Can't open database: %s\n", 
> sqlite3_errmsg(db));
>               sqlite3_close(db);
>               exit(1);
>       }
>
>       sqlite3_busy_timeout(db, 10000);
>
>       sqlite3_exec(db, "BEGIN", NULL, NULL, NULL);
>       error = sqlite3_prepare_v2(db, "select count from table1", 100, &res,
> NULL);
>       if (error != SQLITE_OK)
>       {
>               printf("SQLITE_OK is not OK - %d\n", error);
>               exit(1);
>       }
>
>       while (sqlite3_step(res) == SQLITE_ROW)
>       {
>               count = sqlite3_column_int(res, 0);
>               printf("%u", count);
>       }
>       sqlite3_finalize(res);
>
>       count++;
>       sqlite_query = sqlite3_mprintf("update table1 set count = %d",
> count);
>       error = sqlite3_exec(db, sqlite_query, NULL, NULL, NULL);
>       if(error != SQLITE_OK)
>       {
>               puts(" - error updating count");
>       }
>       else
>       {
>               puts(" - updated OK");
>       }
>
>       sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
>       sqlite3_free(sqlite_query);
>       sqlite3_close(db);
>
>       return 0;
> }
>
> When I run this serially, I get:
> $ ./demo
> 214 - updated OK
> $ ./demo
> 215 - updated OK
> $ ./demo
> 216 - updated OK
>
> When I run it in parallel, using this script:
>
> #!/bin/sh
>
> count=0
> limit=4
> while [ ${count} -lt ${limit} ]
> do
>       count=`expr $count + 1`
>       ./demo 2>&1 &
> done
>
> I get:
>
> $ ./multi.sh
> 219 - updated OK
> 219 - error updating count
> 220 - updated OK
> 220 - error updating count
>
> I thought that this line...
>
>                                  sqlite3_busy_timeout(db,
> 10000);
>
> ...would give me a 10 second window where SQLite would gracefully,
> invisibly take care of locking for me, as per this documentation:
>
> "This routine sets a busy handler that sleeps for a specified amount
> of time when a table is locked. The handler will sleep multiple times
> until at least "ms" milliseconds of sleeping have accumulated. After
> at least "ms" milliseconds of sleeping, the handler returns 0 which
> causes sqlite3_step() to return SQLITE_BUSY or SQLITE_IOERR_BLOCKED."
>
> But things go wrong long before 10 seconds have elapsed, and I get the
> error messages shown.
>
> Now, clearly, SQLite is capable of handling locks, and the fault lies
> with me. Maybe I've simply missed a nuance somewhere, or maybe my
> understanding is fundamentally wrong. I just don't know. I would turn
> cartwheels if somebody could show me what I'm doing wrong in my code,
> and spoon-feed me the canonical way of doing it the right way. I am
> keen to use SQLite, but this locking impass is currently a sticking
> point for me.
>
> Many thanks
> Peter
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to