On 02/25/2016 09:53 AM, sanhua.zh wrote:
> So can this be understood as, if I run my code in WAL, I can invoke busy 
> handler even it in TRAN_READ?


No. The busy-handler is not invoked when trying to upgrade from a read 
to a write transaction. Regardless of journal mode.

Dan.


>
>
> ????
> ???:Dan Kennedydanielk1977 at gmail.com
> ???:sqlite-userssqlite-users at mailinglists.sqlite.org
> ????:2016?2?24?(??)?23:52
> ??:Re: [sqlite] Why skip invoking busy handler 
> whilepBt-inTransaction!=TRANS_NONE
>
>
> 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 
> _______________________________________________ sqlite-users mailing list 
> sqlite-users at mailinglists.sqlite.org 
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> _______________________________________________
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Reply via email to