review(bp): move SaveChanges into repo with race protection; JST constant
GetOrCreateProgressAsync now persists the new row itself and catches DbUpdateException on unique-constraint violations — concurrent /info calls no longer throw 500s. BattlePassService no longer calls SaveChangesAsync after the get-or-create. FormatWireDate uses a named JstOffset constant instead of an inline TimeSpan.FromHours(9). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,18 @@ public sealed class ViewerBattlePassRepository : IViewerBattlePassRepository
|
||||
WeeklyPeriodStart = null,
|
||||
};
|
||||
_db.ViewerBattlePassProgress.Add(entry);
|
||||
return entry;
|
||||
try
|
||||
{
|
||||
await _db.SaveChangesAsync(ct);
|
||||
return entry;
|
||||
}
|
||||
catch (DbUpdateException)
|
||||
{
|
||||
// Concurrent /info call won the race; re-read the row the other thread persisted.
|
||||
_db.Entry(entry).State = EntityState.Detached;
|
||||
return await _db.ViewerBattlePassProgress
|
||||
.FirstAsync(p => p.ViewerId == viewerId && p.SeasonId == seasonId, ct);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<List<ViewerBattlePassClaimEntry>> GetClaimsAsync(long viewerId, int seasonId, CancellationToken ct) =>
|
||||
|
||||
Reference in New Issue
Block a user