fix: serialise redirect writes so concurrent saves cannot store a loop (WR-10)

The save-time simulation read the rules at READ COMMITTED without a lock,
so A -> B and B -> A written concurrently both passed. CheckRedirect,
AddressChanged and every batch now take a transaction-level advisory lock
before they read the rules.
This commit is contained in:
2026-10-27 15:29:08 +01:00
parent cb614cb1fb
commit c2f136ad7d
5 changed files with 69 additions and 1 deletions

View File

@@ -96,6 +96,9 @@ func (s *Service) applyAddressRedirects(ctx context.Context, tx *gorm.DB, res *A
return nil
}
if err := lockRedirectWrites(tx.WithContext(ctx)); err != nil {
return err
}
rules, err := LoadRedirects(tx)
if err != nil {
return err