/ Check-in [221ff63e]
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 | exp-busy-snapshot-fix
Files: files | file ages | folders
SHA3-256: 221ff63e7902226ebf728bb7442727420636831163708f360724506ce9487ab6
User & Date: dan 2018-07-05 15:46:55
Context
2018-07-05
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
15:46
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: 221ff63e 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 Unified Diffs Show Whitespace Changes Patch

Changes to src/btree.c.

3420
3421
3422
3423
3424
3425
3426








3427
3428
3429
3430
3431
3432
3433
      if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){
        rc = sqlite3PagerWrite(pPage1->pDbPage);
        if( rc==SQLITE_OK ){
          put4byte(&pPage1->aData[28], pBt->nPage);
        }
      }
    }








  }


trans_begun:
  if( rc==SQLITE_OK ){
    if( pSchemaVersion ){
      *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);







>
>
>
>
>
>
>
>







3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
      if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){
        rc = sqlite3PagerWrite(pPage1->pDbPage);
        if( rc==SQLITE_OK ){
          put4byte(&pPage1->aData[28], pBt->nPage);
        }
      }
    }
  }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
    /* Even if there was no transaction opened when this function was
    ** called, a race condition may cause an SQLITE_BUSY_SNAPSHOT error
    ** in wal mode (since the code above opens a read-transaction and then
    ** upgrades it to a write-transaction - it does not take the write lock
    ** atomically). In this case change the error code to SQLITE_BUSY.  */
    assert( wrFlag );
    rc = SQLITE_BUSY;
  }


trans_begun:
  if( rc==SQLITE_OK ){
    if( pSchemaVersion ){
      *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);

Changes to test/walprotocol2.test.

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  }
}
do_catchsql_test 2.2 {
  BEGIN EXCLUSIVE;
} {1 {database is locked}}
do_test 2.3 {
  sqlite3_extended_errcode db
} {SQLITE_BUSY_SNAPSHOT}

#---------------------------------------------------------------
# Same again, but with a busy-handler. This time, following the
# SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the 
# whole thing retried from the beginning. This time it succeeds.
#
proc lock_callback {method filename handle lock} {







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  }
}
do_catchsql_test 2.2 {
  BEGIN EXCLUSIVE;
} {1 {database is locked}}
do_test 2.3 {
  sqlite3_extended_errcode db
} {SQLITE_BUSY}

#---------------------------------------------------------------
# Same again, but with a busy-handler. This time, following the
# SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the 
# whole thing retried from the beginning. This time it succeeds.
#
proc lock_callback {method filename handle lock} {