Handle SQLITE_SCHEMA error in db_exec()

This happens under database load with many concurrent threads doing updates;
queries failing with SQLITE_SCHEMA at step time need to retried from scratch
until they succeeded or hit a best-effort limit of 5 retries.
This commit is contained in:
Julien BLACHE 2011-05-28 10:48:31 +02:00
parent 4594cc3d63
commit 4f3635e354

View File

@ -535,30 +535,35 @@ static int
db_exec(const char *query, char **errmsg) db_exec(const char *query, char **errmsg)
{ {
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
int try;
int ret; int ret;
*errmsg = NULL; *errmsg = NULL;
ret = db_blocking_prepare_v2(query, -1, &stmt, NULL); for (try = 0; try < 5; try++)
if (ret != SQLITE_OK)
{ {
*errmsg = sqlite3_mprintf("prepare failed: %s", sqlite3_errmsg(hdl)); ret = db_blocking_prepare_v2(query, -1, &stmt, NULL);
return ret; if (ret != SQLITE_OK)
} {
*errmsg = sqlite3_mprintf("prepare failed: %s", sqlite3_errmsg(hdl));
return ret;
}
while ((ret = db_blocking_step(stmt)) == SQLITE_ROW) while ((ret = db_blocking_step(stmt)) == SQLITE_ROW)
; /* EMPTY */ ; /* EMPTY */
sqlite3_finalize(stmt);
if (ret != SQLITE_SCHEMA)
break;
}
if (ret != SQLITE_DONE) if (ret != SQLITE_DONE)
{ {
*errmsg = sqlite3_mprintf("step failed: %s", sqlite3_errmsg(hdl)); *errmsg = sqlite3_mprintf("step failed: %s", sqlite3_errmsg(hdl));
sqlite3_finalize(stmt);
return ret; return ret;
} }
sqlite3_finalize(stmt);
return SQLITE_OK; return SQLITE_OK;
} }