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