Fix #4830: Prevent multiple public submissions using atomic DB locking #4832 (Add transaction import from django.db) #4833 #4834
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #4830
Summary
When
is_restricted_to_select_one_submission=Trueon a challenge phase, two or more concurrent requests can toggle different submissions as public at the same time. This happens because the visibility check uses a non-atomic.count()query, allowing both requests to observe stale state and proceed, resulting in multiple public submissions for the same team and phase.This PR introduces an atomic database-level lock using
transaction.atomic()andselect_for_update()to guarantee exclusive access to the existing public submissions when toggling visibility.This ensures the business rule is always enforced:
Root Cause
The existing logic:
is vulnerable to race conditions:
count() == 1→ Truecount() == 1→ True (no change committed yet)Because there is no row-level lock, both transactions succeed.
Fix
transaction.atomic().select_for_update()to lock existing public submission rows until the update completesTechnical Details
Notes
This PR does not modify the public/private rules beyond fixing the race condition.
The logic path for non-public submissions is unaffected.
Testing
Let me know if you would like me to add explicit unit tests for the concurrency scenario.