Fix the validation clicker issue, now the note is safe

This commit is contained in:
Yohann D'ANELLO 2020-09-14 09:05:35 +02:00
parent 872fd8f86d
commit dbc6fbbf71
1 changed files with 11 additions and 8 deletions

View File

@ -176,9 +176,10 @@ class Transaction(PolymorphicModel):
created = self.pk is None created = self.pk is None
to_transfer = self.total to_transfer = self.total
if not created and not self.valid: if not created:
# Revert old transaction # Revert old transaction
old_transaction = Transaction.objects.get(pk=self.pk) # We make a select for update to avoid concurrency issues
old_transaction = Transaction.objects.select_for_update().get(pk=self.pk)
# Check that nothing important changed # Check that nothing important changed
if not hasattr(self, "_force_save"): if not hasattr(self, "_force_save"):
for field_name in ["source_id", "destination_id", "quantity", "amount"]: for field_name in ["source_id", "destination_id", "quantity", "amount"]:
@ -217,10 +218,6 @@ class Transaction(PolymorphicModel):
# When source == destination, no money is transferred and no transaction is created # When source == destination, no money is transferred and no transaction is created
return return
# We refresh the notes with the "select for update" tag to avoid concurrency issues
self.source = Note.objects.filter(pk=self.source_id).select_for_update().get()
self.destination = Note.objects.filter(pk=self.destination_id).select_for_update().get()
# Check that the amounts stay between big integer bounds # Check that the amounts stay between big integer bounds
diff_source, diff_dest = self.validate() diff_source, diff_dest = self.validate()
@ -239,8 +236,14 @@ class Transaction(PolymorphicModel):
super().save(*args, **kwargs) super().save(*args, **kwargs)
# Save notes # Save notes
Note.objects.filter(pk=self.source_id).update(balance=F("balance") + diff_source) self.source.refresh_from_db()
Note.objects.filter(pk=self.destination_id).update(balance=F("balance") + diff_dest) self.source.balance += diff_source
self.source._force_save = True
self.source.save()
self.destination.refresh_from_db()
self.destination.balance += diff_dest
self.destination._force_save = True
self.destination.save()
@property @property
def total(self): def total(self):