So can this be understood as, if I run my code in WAL, I can invoke busy 
handler even it in TRAN_READ?


????
???: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

Reply via email to