From 4d981e3b2eeaf7073a3fab9c200b04b2d43b4da7 Mon Sep 17 00:00:00 2001 From: alim Date: Sun, 16 Nov 2025 20:56:45 +0800 Subject: [PATCH] fix: make rating aggregation updates atomic - Add SELECT FOR UPDATE to lock GeneratedRoadmap row during counter updates - Prevents race condition where concurrent rating submissions corrupt counters - Fixes issue where rating_count could be 1 when 2 ratings were actually submitted - Ensures accurate rating averages in UI Without row locking, two users submitting ratings simultaneously could both read the same initial counters (e.g., 0) and each write back their own incremented values. The last commit would win, causing the first rating to be lost from the aggregated stats even though both roadmap_ratings rows were successfully inserted. All 8 rating tests passing. --- commitly-backend/app/services/roadmap_rating_store.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commitly-backend/app/services/roadmap_rating_store.py b/commitly-backend/app/services/roadmap_rating_store.py index 8ce5a06..710f116 100644 --- a/commitly-backend/app/services/roadmap_rating_store.py +++ b/commitly-backend/app/services/roadmap_rating_store.py @@ -88,10 +88,11 @@ def action() -> RoadmapRating: ) self._session.add(record) - # Update aggregated stats on GeneratedRoadmap + # Update aggregated stats on GeneratedRoadmap atomically roadmap = ( self._session.query(GeneratedRoadmap) .filter_by(repo_full_name=repo_full_name) + .with_for_update() .one_or_none() )