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