Use select for update before creating invoice for conference registration
authorMagnus Hagander <magnus@hagander.net>
Tue, 5 Nov 2024 12:41:31 +0000 (13:41 +0100)
committerMagnus Hagander <magnus@hagander.net>
Tue, 5 Nov 2024 12:41:31 +0000 (13:41 +0100)
Do this only for POSTs, but without that if the user clicks the confirm
button twice in a row Really Fast, there's a race condition whereby two
invoices can be created for the same registration, which is not
supported elsewhere in the system.

This probably likely exists in other places as well, but it becomes a
lot more apparent when it comes to creating invoices as the generation
of the PDFs take some time.

postgresqleu/confreg/views.py

index b274fdf3ee08575687e86b5a04df374e2642fbf7..106df05772418f86b756cb5e501e97fa859acc30 100644 (file)
@@ -2138,7 +2138,11 @@ def confirmreg(request, confname):
     # cost of the registration, minus any discounts found (including
     # complete-registration vouchers).
     conference = get_conference_or_404(confname)
-    reg = get_object_or_404(ConferenceRegistration, attendee=request.user, conference=conference)
+    if request.method != 'POST':
+        reg = get_object_or_404(ConferenceRegistration, attendee=request.user, conference=conference)
+    else:
+        reg = get_object_or_404(ConferenceRegistration.objects.select_for_update(), attendee=request.user, conference=conference)
+
     # This should never happen since we should error out in the form,
     # but make sure we don't accidentally proceed.
     if not reg.regtype: