The sha256 lookup before inserting an image row can lose a race to another
worker importing a second copy of the same picture. The unique index then
refused the insert. A media import retried behind the whole import queue, and
the recovery sweep ran it a second time. An archive swallowed the error, failed
on the dead transaction, and its row stayed 'processing' because the failure
mark could not commit either.
- Importer._store_new_record inserts under a savepoint; on a conflict the file
is filed as a duplicate of the row that won (_file_as_duplicate, now shared
by every duplicate branch). _import_media removes its stray library copy.
- _import_archive commits its post before extracting; the member loop rolls
back a failed member and lets SoftTimeLimitExceeded through.
- _mark_failed rolls back before writing the failure.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>