On 02/24/2016 08:32 PM, sanhua.zh wrote:
> In the source code of SQLite, btree.c, sqlite3BtreeBeginTrans function,
> The code
>
>
>   do {
>    /* Call lockBtree() until either pBt-pPage1 is populated or
>    ** lockBtree() returns something other than SQLITE_OK. lockBtree()
>    ** may return SQLITE_OK but leave pBt-pPage1 set to 0 if after
>    ** reading page 1 it discovers that the page-size of the database
>    ** file is not pBt-pageSize. In this case lockBtree() will update
>    ** pBt-pageSize to the page-size of the file on disk.
>    */
>    while( pBt-pPage1==0  SQLITE_OK==(rc = lockBtree(pBt)) );
>
>
>    if( rc==SQLITE_OK  wrflag ){
>     if( (pBt-btsFlags  BTS_READ_ONLY)!=0 ){
>      rc = SQLITE_READONLY;
>     }else{
>      rc = sqlite3PagerBegin(pBt-pPager,wrflag1,sqlite3TempInMemory(p-db));
>      if( rc==SQLITE_OK ){
>       rc = newDatabase(pBt);
>      }
>     }
>    }
>
>    if( rc!=SQLITE_OK ){
>     unlockBtreeIfUnused(pBt);
>    }
>   }while( (rc0xFF)==SQLITE_BUSY  pBt-inTransaction==TRANS_NONE
>       btreeInvokeBusyHandler(pBt) );
>
>
>
>
> You can see pBt-inTransaction==TRANS_NONE is one of the condition that invoke 
> busy handler.
> There is a simple way to simulate a situation that does not invoke busy 
> handler:
> 1. begin a transaction without ?IMMEDIATE? and ?EXCLUSIVE?
> 2. run a read operation, like ?SELECT?. This will let pBt-inTransaction be 
> TRANS_READ
> 3. run a write operation, which will invoke sqlite3BtreeBeginTrans again. And 
> if it becomes SQLITE_BUSY, then btreeInvokeBusyHandler will be skiped and no 
> retry will happen.
>
>
> So it?s the question I confused. Why SQLite skip invoking busy handler while 
> it's in TRANS (either read or write) ?

Assuming you're not using wal-mode, it's because the two processes will 
be waiting for each other.

The transaction opened in step 1 cannot be committed until the read-only 
transaction started in step 2 has ended. So if you did invoke the 
busy-handler in step 3, the two processes would each be waiting for the 
other to give up. Not much point to that.

In wal-mode it's a little different. The transaction opened in step 1 
could be committed, but attempting to open the write-transaction in step 
3 following that would fail with SQLITE_BUSY_SNAPSHOT.


Dan.



> _______________________________________________
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to