In production environments where Django is running on Apache or with multiple Gunicorn workers, it runs the risk of concurrency issues.
As such, I was pretty surprised to find that Django's ORM doesn't explicitly support table/row locking. It supports transactions very handedly, but that only solves half of the concurrency problem.
With a MySQL backend, what is the correct way to perform locking in Django? Or is there something else at play in Django's framework that makes them unnecessary?
解决方案
Django does not explicitly provide an API to perform table locking. In my experience, well-designed code rarely needs to lock a whole table, and most concurrency issues can be solved with row-level locking. It's an last-ditch effort: it doesn't solve concurrency, it simply kills any attempt at concurrency.
If you really need table-level locking, you can use a cursor and execute raw SQL statements:
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("LOCK TABLES %s READ", [tablename])
try:
...
finally:
cursor.execute("UNLOCK TABLES;")