I'm concerned about one thing.
Using Django 1.7 (MySQL in the most default installation) I'm making a POST to a Django REST Framework APIView
.
Over there I'm doing a:
try:
MyModel.objects.get(**some_kwargs)
except MyModel.DoesNotExist:
MyModel.objects.custom_create(**some_kwargs) # This also creates relative models
Now what will happen if I'll do plenty of concurrent requests?
As I guess you expect I want only the first concurrent request to create an object and any other should get the created one.
Am I ready to go thanks do Django? Have to study about isolation, transactions, atomicity? Or is it more about locking the table? How to (unit) test it?
Please guide me.
This is not enough to avoid race conditions, as another request can create the model you intended to retrieve between get()
and custom_create()
. If uniqueness is enforced on a database level, your custom_create()
method can fail with an IntegrityError
. If it is not, your method is fine, but you cannot prevent duplicate entries due to race conditions.
Django provides the get_or_create()
function. This safeguards against race conditions if uniqueness is enforced by your database. It uses the create()
method, however, not your custom_create()
method, so you'll have to override it if it is acceptable. Otherwise, you can checkout out the source code for get_or_create()
and implement it yourself with your custom create method.
The core assumption of get_or_create
is that uniqueness is enforced on a database level. Due to this enforcement, create
fails if a race condition occurs, and get_or_create
can fall back to fetching the object created during the race condition. If this enforcement is missing, the create
doesn't fail during a race condition, and a duplicate entry (with a different PK) will be created.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With