> Den 10/02/2015 kl. 23.45 skrev Carl Meyer <c...@oddbird.net>:
> 
> Yes, that's what I said :-)

Thanks for the great explanations; I didn't see your previous answer before 
posting my latest reply, hence the duplicate explanations :-)
> 
>> My code relies on isolation level "Serializable" for a cache.get()
>> followed by cache.add() to be reliable, but Django uses the default
>> from PostgreSQL.
> 
> I don't think you need full Serializable, Repeatable Read should be
> sufficient. Serializable is dangerous, has a tendency to cause deadlocks
> (as I think you've discovered). Even with Repeatable Read, you'll need
> be a bit careful about any long-running processes that might hold open a
> transaction.

I was thinking Seralizable is needed since cache.get() is a query that could 
result in a phantom read. But since I have multiple long-running management 
jobs and incoming changes from a REST API, I also think I'll bee too vulnerable 
to deadlocks if I change the isolation level.

> But `self.connection.set_isolation_level()` is called in
> `_set_autocommit()`, and that should be sufficient. (The
> `_set_isolation_level()` method is dead code in 1.7 and has since been
> removed, but what really matters is that
> `self.connection.set_isolation_level()` is called.)

It's only called if self.psycopg2_version < (2, 4, 2), at least in the file I'm 
looking at. My version is 2.5.2.

> OPTIONS['autocommit'] has been ignored since Django 1.6, as the docs you
> linked clearly state: "This configuration is ignored and can be safely
> removed."
> 
> You're looking for
> https://docs.djangoproject.com/en/1.7/ref/settings/#autocommit instead.

Right you are :-) I should get some sleep.

> You could switch to Repeatable Read (but leave AUTOCOMMIT on). Or (what
> I would probably do) you could leave the isolation level at the default
> (since it's the default for Django, some parts of Django, such as
> QuerySet.get_or_create(), may not work correctly under a different
> isolation level) and simply update your locking logic to guard against
> that race condition (if the add fails, assume that another process has
> grabbed the lock in the interim).

Yeah, I think I'll do just that. My production code is a bit more complicated 
since it relies on two cache.get()'s before the cache.add(), but that will 
probably just have to go away.

Thanks again for you excellent help,
Erik

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/C42D1493-F3D4-416E-A6A9-AA78BB589F78%40cederstrand.dk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to