Thanks a lot for the explanation Igor.

--  
Marco Bambini



On May 14, 2009, at 1:55 PM, Igor Tandetnik wrote:

> "Marco Bambini" <ma...@sqlabs.net> wrote
> in message news:aa7dd05f-4679-43dd-9dd3-2ba6b98af...@sqlabs.net
>> I have two threads that are writing 2000 rows each to the same
>> database at the same time.
>> I am using sqlite 3.6.13 compiled with SQLITE_THREADSAFE=1.
>>
>> Each client executes this code (pseudo C code):
>> void write (sqlite3 *db) {
>> int i;
>>
>> for (i=1; i<=2000; i++) {
>> if (sqlite3_get_autocommit(db) != 0) sqlite3_exec(db, "BEGIN
>> IMMEDIATE;", ...);
>> sqlite3_exec(db, "INSERT INTO....", ...);
>> if (sqlite3_get_autocommit(db) == 0) sqlite3_exec(db,  
>> "COMMIT;", ...);
>> }
>> }
>> and db is shared between the two clients.
>
> You have a race condition here: between the calls to
> sqlite3_get_autocommit and sqlite3_exec, the other thread could very
> well have issued a BEGIN or a COMMIT of its own. Between the time you
> check the condition and the time you act on it, the condition could  
> have
> changed.
>
> Besides, the documentation on sqlite3_get_autocommit has this  
> sentence:
> If another thread changes the autocommit status of the database
> connection while this routine is running, then the return value is
> undefined. In other words, sqlite3_get_autocommit is explicitly not
> thread-safe.
>
> Since you only run one INSERT per transaction anyway, why do you feel
> you need explicit BEGIN and COMMIT?
>
>> At the end of the loop, instead of having 4000 rows I have 3976 rows
>> (it's random, sometimes I have 3972 or 3974).
>> sqlite3_exec doesn't returns any error during the INSERT statement,
>> but I have some errors during the BEGIN IMMEDIATE, errors are all:
>> SQL logic error or missing database (printed with sqlite3_errmsg).
>
> Your use of sqlite3_errmsg is itself very likely a race. Between the
> time you detect an error and the time you retrieve error message, the
> other thread could have run some statements that modify the error
> message. Moreover, between the time you call sqlite3_errmsg and the  
> time
> you actually print the string pointed to by the char* pointer the
> function returns, the string may be modified or even deallocated.
>
> Igor Tandetnik
>
>
>
> _______________________________________________
> 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