database: retry transaction if sqlite returns busy error (#17297)

Adds an additional sqlite error code 5 (SQLITE_BUSY) to the
transaction retry handler to add retries when sqlite
returns database is locked error.
More info: https://www.sqlite.org/rescode.html#busy
Backports #17276 for v6.2.x
This commit is contained in:
Marcus Efraimsson
2019-05-27 14:30:34 +02:00
parent b0647a4537
commit efd14ac7db
2 changed files with 9 additions and 9 deletions
+3 -3
View File
@@ -88,12 +88,12 @@ func (ss *SqlStore) inTransactionWithRetryCtx(ctx context.Context, callback dbTr
err = callback(sess)
// special handling of database locked errors for sqlite, then we can retry 3 times
// special handling of database locked errors for sqlite, then we can retry 5 times
if sqlError, ok := err.(sqlite3.Error); ok && retry < 5 {
if sqlError.Code == sqlite3.ErrLocked {
if sqlError.Code == sqlite3.ErrLocked || sqlError.Code == sqlite3.ErrBusy {
sess.Rollback()
time.Sleep(time.Millisecond * time.Duration(10))
sqlog.Info("Database table locked, sleeping then retrying", "retry", retry)
sqlog.Info("Database locked, sleeping then retrying", "error", err, "retry", retry)
return ss.inTransactionWithRetryCtx(ctx, callback, retry+1)
}
}
+6 -6
View File
@@ -25,12 +25,12 @@ func (ss *SqlStore) inTransactionWithRetry(ctx context.Context, fn func(ctx cont
err = fn(withValue)
// special handling of database locked errors for sqlite, then we can retry 3 times
// special handling of database locked errors for sqlite, then we can retry 5 times
if sqlError, ok := err.(sqlite3.Error); ok && retry < 5 {
if sqlError.Code == sqlite3.ErrLocked {
if sqlError.Code == sqlite3.ErrLocked || sqlError.Code == sqlite3.ErrBusy {
sess.Rollback()
time.Sleep(time.Millisecond * time.Duration(10))
ss.log.Info("Database table locked, sleeping then retrying", "retry", retry)
ss.log.Info("Database locked, sleeping then retrying", "error", err, "retry", retry)
return ss.inTransactionWithRetry(ctx, fn, retry+1)
}
}
@@ -69,12 +69,12 @@ func inTransactionWithRetryCtx(ctx context.Context, callback dbTransactionFunc,
err = callback(sess)
// special handling of database locked errors for sqlite, then we can retry 3 times
// special handling of database locked errors for sqlite, then we can retry 5 times
if sqlError, ok := err.(sqlite3.Error); ok && retry < 5 {
if sqlError.Code == sqlite3.ErrLocked {
if sqlError.Code == sqlite3.ErrLocked || sqlError.Code == sqlite3.ErrBusy {
sess.Rollback()
time.Sleep(time.Millisecond * time.Duration(10))
sqlog.Info("Database table locked, sleeping then retrying", "retry", retry)
sqlog.Info("Database locked, sleeping then retrying", "error", err, "retry", retry)
return inTransactionWithRetry(callback, retry+1)
}
}