I have a Django-based webapp that is using PostgreSQL as the backend via psycopg2. Right now we're on postgres 8.4.x but will move to 9.1.x in the future. We're using the current stable release of Django (1.3.1).
I want to enable stricter transaction isolation (as per the postgres docs) at either the REPEATABLE READ or SERIALIZABLE levels. From the psycopg2 source, the ones available are:
"""Isolation level values."""
ISOLATION_LEVEL_AUTOCOMMIT = 0
ISOLATION_LEVEL_READ_UNCOMMITTED = 1
ISOLATION_LEVEL_READ_COMMITTED = 2
ISOLATION_LEVEL_REPEATABLE_READ = 3
ISOLATION_LEVEL_SERIALIZABLE = 4
Unfortunately, Django 1.3.1's psycopg2 backend implementation of _set_isolation_level() includes assert level in (0, 1) which seems to preclude using this method to set the isolation level as high as I want right now.
In a recent commit to Django's trunk, it's nice to see that this restriction has been relaxed to allow levels up to 4, however, there still does not appear to be an option via the normal Django settings to actually indicate to the backend that you want a higher isolation level than ISOLATION_LEVEL_READ_COMMITTED. In other words, whilst _set_isolation_level() will now accept a level up to 4, there is no config-based way to actually cause it to be called with 4 as the argument.
Questions:
Assuming I was willing to start using Django's devel version to get this change, what would be the correct / recommended way to call _set_isolation_level() manually given that there is no config option that will result in it being called with the isolation level I want?
Assuming I'm not willing to use Django's devel version, what is the recommended way to pass the desired isolation level through to psycopg2 using Django 1.3.1?
Do both current and future versions of Django make it hard to specify these higher isolation levels because they cause huge problems in practice? (i.e. should I be doing this at all?) Keep in mind, our app has relatively low DB throughput with large, infrequent transactions with an extremely high desire for consistency.
Thanks in advance for any suggestions.
The easiest and most compatible way of doing this would be to write your own DB adapter that inherits from django's default and overrides the methods so that you set your own isolation level.
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