fix(server): reduce SQLite "database busy" errors (#3760)

* fix(scanner): remove transactions where they are not strictly needed

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(server): force setStar transaction to start as IMMEDIATE

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(server): encapsulated way to upgrade tx to write mode

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(server): use tx immediate for some playlist endpoints

Signed-off-by: Deluan <deluan@navidrome.org>

* make more transactions immediate (#3759)

---------

Signed-off-by: Deluan <deluan@navidrome.org>
Co-authored-by: Kendall Garner <17521368+kgarner7@users.noreply.github.com>
This commit is contained in:
Deluan Quintão 2025-02-26 19:01:49 -08:00 committed by GitHub
parent d6ec52b9d4
commit 1468a56808
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 120 additions and 115 deletions

View file

@ -138,24 +138,22 @@ func (s *scannerImpl) runRefreshStats(ctx context.Context, state *scanState) fun
log.Debug(ctx, "Scanner: No changes detected, skipping refreshing stats")
return nil
}
return s.ds.WithTx(func(tx model.DataStore) error {
start := time.Now()
stats, err := tx.Artist(ctx).RefreshStats()
if err != nil {
log.Error(ctx, "Scanner: Error refreshing artists stats", err)
return fmt.Errorf("refreshing artists stats: %w", err)
}
log.Debug(ctx, "Scanner: Refreshed artist stats", "stats", stats, "elapsed", time.Since(start))
start := time.Now()
stats, err := s.ds.Artist(ctx).RefreshStats()
if err != nil {
log.Error(ctx, "Scanner: Error refreshing artists stats", err)
return fmt.Errorf("refreshing artists stats: %w", err)
}
log.Debug(ctx, "Scanner: Refreshed artist stats", "stats", stats, "elapsed", time.Since(start))
start = time.Now()
err = tx.Tag(ctx).UpdateCounts()
if err != nil {
log.Error(ctx, "Scanner: Error updating tag counts", err)
return fmt.Errorf("updating tag counts: %w", err)
}
log.Debug(ctx, "Scanner: Updated tag counts", "elapsed", time.Since(start))
return nil
}, "scanner: refresh stats")
start = time.Now()
err = s.ds.Tag(ctx).UpdateCounts()
if err != nil {
log.Error(ctx, "Scanner: Error updating tag counts", err)
return fmt.Errorf("updating tag counts: %w", err)
}
log.Debug(ctx, "Scanner: Updated tag counts", "elapsed", time.Since(start))
return nil
}
}