SQLite

Check-in [221ff63e79]
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
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.944
Context
2018-07-05
17:03
Fix a typo inside an assert() statement introduced by the previous commit. (Closed-Leaf check-in: e335772847 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: 221ff63e79 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: 5a12db75d1 user: dan tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/btree.c.
3420
3421
3422
3423
3424
3425
3426








3427
3428
3429
3430
3431
3432
3433
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
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}
} {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} {