问题
I have a Django 1.7 beta 1 project with a standard user signup form.
Conceptually, it makes sense for the form validation to fail if the username is already taken. However, the form validation and the saving of the successfully created user model are separate steps, so there's a race condition where the validation can pass but the actual user.save()
can fail with an IntegrityError
.
I'm unclear on what happens if both the form validation and the user.save()
step are wrapped in the same transaction.atomic()
block -- my assumption is that postgres will not create any locks when the table is read to check if the row exists, and therefore the transaction will not prevent the race condition at all.
Assuming that's the case, what is the best way to handle this? Here are the options I'm considering so far:
- Skip the username uniqueness validation entirely and just catch the
IntegrityError
on save time, adding to the form errors list manually. This is bulletproof, but moves some validation logic outside of the form definition. - Do both the validation step and the try/except block around the
IntegrityError
. This may add duplicate code, but now the form works in isolation and the use of the form in the view doesn't cause a race condition.
来源:https://stackoverflow.com/questions/22618605/avoiding-race-condition-between-validation-for-uniqueness-and-insertion