On Tuesday 05 March 2013, Aymeric Augustin wrote:
> On 5 mars 2013, at 12:50, Shai Berger <[email protected]> wrote:
> > At least the "delete duplicates" example I've pointed to shows, that it's
> > quite easy to write code that is correct now, under the defaults, with
> > MySql and will break with the change.
> 
> http://stackoverflow.com/questions/8965391/delete-duplicate-rows-in-django-
> db
> 
> In fact this code is already unsafe under MySQL with "repeatable read";
> you need "serializable" to make it safe.
> 

I'm not sure what you mean by "unsafe". 

Version 1: code in the question

        rows = MyModel.objects.all()
        for row in rows:
            try:
                MyModel.objects.get(photo_id=row.photo_id)
            except:
                row.delete()

When Django checks for a second record on get() it reads the second record, so 
a repeatable-read transaction would acquire an exclusive read lock on it. This 
makes it impossible for another transaction to delete the second row before 
the first finishes.

Version 2: code in the first answer.

        for row in MyModel.objects.all():
            if MyModel.objects.filter(photo_id=row.photo_id).count() > 1:
                row.delete()

To the best of my understanding, a repeatable-read transaction gets a read 
lock on all records participating in a count, so again, nobody can delete the 
other records before the transaction finishes.

With database-level autocommit, both versions are susceptible to having the 
"other" record deleted between the read that detects it and the deletion of 
the current row (deemed a redundant copy).

> The current behavior doesn't map to any common programming idiom and
> doesn't make much sense in general. The only explanation I've found is "we
> had to commit after making changes otherwise they weren't saved".

There is no argument that the change is wanted. The only issue I'm -1 on is 
changing the default with no deprecation and no option to use existing 
behavior.

> As a consequence, code written "unwittingly" is more likely to be incorrect
> than correct.

Still not a license to break it when it is correct, IMO.

Shai.

-- 
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 [email protected].
To post to this group, send email to [email protected].
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