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

Reply via email to