select_for_update is the simplest way to acquire a lock on an object, provided your database supports it. PostgreSQL, Oracle, and MySQL, at least, support it, according to the Django docs.
Example code:
import time
from django.contrib.auth import get_user_model
from django.db import transaction
User = get_user_model()
@transaction.atomic
def my_example_function():
my_user = User.objects.all()[0]
print("Acquiring lock...")
locked_user = User.objects.select_for_update().get(pk=my_user.pk)
print(locked_user)
while True:
print("sleeping {}".format(time.time()))
print("holding lock on {}".format(locked_user))
time.sleep(5)
Note that you have to use select_for_update
within a transaction, hence the @transaction.atomic
decorator.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…