There was a discussion on the subject 
here<https://groups.google.com/d/topic/django-developers/wvpysb-fXtc/discussion>
.

Le jeudi 4 avril 2013 23:23:43 UTC-4, Matteius a écrit :
>
>
> Greetings Developers,
>
> Today at work I fixed a thread safety issue in our code whereby two 
> threads were calling get_or_create on the same URL which has a uniqueness 
> constraint.  It was in some cases raising an IntegrityError in sentry even 
> after I converted our atomically incorrect code to use get_or_create 
> proving to me it must be two different threads performing the same action.  
> Let me elaborate ...
>
> Django's get_or_create does a Get, failing that a create, failing that a 
> rollback and another get.   For some reason in MySQL, and to me 
> conceptually the code roll back to prior to the commit when the other 
> thread wins in the create block and saves the object, it still doesn't 
> exist when the other thread tries to get it a final time, because I believe 
> it rolled back to the earlier pre-save savepoint.
>
> Here is the final part of the get_or_create:
>
>                 obj = self.model(**params)
>                 sid = transaction.*savepoint*(using=self.db)
>                 obj.save(force_insert=True, using=self.db)
>                 transaction.savepoint_commit(sid, using=self.db)
>                 return obj, True
>             except *IntegrityError* as e:
>                 transaction.savepoint_rollback(sid, using=self.db)
>                 exc_info = sys.exc_info()
>                 try:
>                     return self.get(**lookup), False
>                 except self.model.DoesNotExist:
>                  *   # Re-raise the IntegrityError* with its original 
> traceback.
>                     six.reraise(*exc_info)
>
>
> The question for me is:  *Why wouldn't we want this to be this way?*:
>
>                 obj = self.model(**params)
>                 sid = transaction.*savepoint*(using=self.db)
>                 obj.save(force_insert=True, using=self.db)
>                 transaction.savepoint_commit(sid, using=self.db)
>                 return obj, True
>             except *IntegrityError* as e:
>                 transaction.savepoint_rollback(sid, using=self.db)
>                 exc_info = sys.exc_info()
>                 try:
>                     *transaction.commit()*  # To refresh the DB view for 
> thread safety
>                     return self.get(**lookup), False   # ... Get succeeds 
> now in a thread unsafe world
>                 except self.model.DoesNotExist:
>                  *   # Re-raise the IntegrityError* with its original 
> traceback.
>                     six.reraise(*exc_info)
>
>
> *Also ---*  On the Django Website, The Django Downloads page Django 
> gtihub tarball master is a 1.4 zip file.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to