I can't argue that SQLite drop SHARED lock, because it can damage
data. For example schema can be different after transaction on db1.

So all this means that If I am using two separate access to one
database with transaction, busy_timeout will always dont work for this
situation.

I see only one solution - using exclusive transaction. Am i right?
--
Alexander Batyrshin aka bash
Biomechanical Artificial Sabotage Humanoid



On Mon, Apr 6, 2009 at 3:04 PM, Dan <[email protected]> wrote:
>
> 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
>
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to