/ Check-in [e6108047]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:In wal mode, if a "BEGIN EXCLUSIVE" command (or any other command that upgrades from no transaction directly to a write transaction) hits an SQLITE_BUSY_SNAPSHOT error, change the error code to SQLITE_BUSY to indicate to the caller that the condition may be transient.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e6108047cb136119d8ed19af010a669ed9750b4e7f991ccabc9e3d15774eda31
User & Date: dan 2018-07-05 17:16:55
Context
2018-07-05
17:35
Fix the .dump command in the command-line shell so that it does not show extraneous SELECT statements when ".echo on" is enabled. check-in: 11763cac user: drh tags: trunk
17:16
In wal mode, if a "BEGIN EXCLUSIVE" command (or any other command that upgrades from no transaction directly to a write transaction) hits an SQLITE_BUSY_SNAPSHOT error, change the error code to SQLITE_BUSY to indicate to the caller that the condition may be transient. check-in: e6108047 user: dan tags: trunk
17:03
Fix a typo inside an assert() statement introduced by the previous commit. Closed-Leaf check-in: e3357728 user: dan tags: exp-busy-snapshot-fix
2018-07-03
20:17
Test that a race condition can cause a "BEGIN EXCLUSIVE" to return SQLITE_BUSY_SNAPSHOT in wal mode. check-in: 5a12db75 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  3371   3371       if( rc==SQLITE_OK && wrflag ){
  3372   3372         if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
  3373   3373           rc = SQLITE_READONLY;
  3374   3374         }else{
  3375   3375           rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
  3376   3376           if( rc==SQLITE_OK ){
  3377   3377             rc = newDatabase(pBt);
         3378  +        }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
         3379  +          /* if there was no transaction opened when this function was
         3380  +          ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
         3381  +          ** code to SQLITE_BUSY. */
         3382  +          rc = SQLITE_BUSY;
  3378   3383           }
  3379   3384         }
  3380   3385       }
  3381   3386     
  3382   3387       if( rc!=SQLITE_OK ){
  3383   3388         unlockBtreeIfUnused(pBt);
  3384   3389       }
................................................................................
  3421   3426           rc = sqlite3PagerWrite(pPage1->pDbPage);
  3422   3427           if( rc==SQLITE_OK ){
  3423   3428             put4byte(&pPage1->aData[28], pBt->nPage);
  3424   3429           }
  3425   3430         }
  3426   3431       }
  3427   3432     }
  3428         -
  3429   3433   
  3430   3434   trans_begun:
  3431   3435     if( rc==SQLITE_OK ){
  3432   3436       if( pSchemaVersion ){
  3433   3437         *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);
  3434   3438       }
  3435   3439       if( wrflag ){

Changes to test/walprotocol2.test.

    68     68     }
    69     69   }
    70     70   do_catchsql_test 2.2 {
    71     71     BEGIN EXCLUSIVE;
    72     72   } {1 {database is locked}}
    73     73   do_test 2.3 {
    74     74     sqlite3_extended_errcode db
    75         -} {SQLITE_BUSY_SNAPSHOT}
           75  +} {SQLITE_BUSY}
    76     76   
    77     77   #---------------------------------------------------------------
    78     78   # Same again, but with a busy-handler. This time, following the
    79     79   # SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the 
    80     80   # whole thing retried from the beginning. This time it succeeds.
    81     81   #
    82     82   proc lock_callback {method filename handle lock} {