简体   繁体   中英

Prevent a race condition where a many requests may concurrent trigger a call which should run only once

So this isn't necessarily a Django question, I'm just having a mental block getting my head around the logic, but I suppose Django might provide some ways to manually lock records that would be helpful.

Essentially, a user may upload one or many files at a time. Each file is uploaded via a separate request. When the user goes above 90% storage quota, I'd like to send an email to them notifying them as such, but I only want to send a single email. So my current workflow is to check their usage, make sure they have not yet been sent a reminder, and :

if usage_pct >= settings.VDISK_HIGH_USAGE_THRESHOLD and disk.last_high_usage_reminder is None:
    disk.last_high_usage_reminder = timezone.now()
    disk.save()
    vdisks_high_usage_send_notice(user)

The above code however often lets more than one email through. So my first thought is to somehow lock the disk record before even checking the value, and then unlock it after saving it. Is it possible and/or advisable, or is there a better method to this?

OK I'm quietly confident I've solved the problem using this answer: https://stackoverflow.com/a/7794220/698289

Firstly, implement this utility function:

@transaction.commit_manually
def flush_transaction():
    transaction.commit()

And then modify my original code to flush and reload the disk record:

flush_transaction()
disk = user.profile.diskstorage
if usage_pct >= settings.VDISK_HIGH_USAGE_THRESHOLD and disk.last_high_usage_reminder is None:
    disk.last_high_usage_reminder = timezone.now()
    disk.save()
    vdisks_high_usage_send_notice(user)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM