Per-transaction isolation level in Django ORM
Asked Answered
P

1

26

Is it possible to set isolation level for custom transaction (but not with raw sql)?

For example, something like:

with transaction.commit_on_success(isolation='SERIALIZABLE'):
    bla
Paulettepauley answered 9/12, 2014 at 19:0 Comment(0)
S
28

As far as I know, there's no way to temporarily change the transaction isolation level in Django for an existing database connection(s).

However, you could setup another database connection(s) that mirrors your default database connection(s) but sets the transaction isolation level.

E.g. in your settings.py:

    DATABASES = {
        'default': {
            'NAME': 'app_data',
            'ENGINE': 'django.db.backends.postgresql',
            'USER': 'postgres_user',
            'PASSWORD': 's3krit',
        },
        'serializable': {
            'NAME': 'app_data',
            'ENGINE': 'django.db.backends.postgresql',
            'USER': 'postgres_user',
            'PASSWORD': 's3krit',
            'OPTIONS': {
                'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE,
            },
        },
    }

To use the serializable transaction level, you could:

  1. Use the using() QuerySet method e.g. User.objects.using('serializable').all

  2. Add a custom manager that specifies the database connection with the transaction isolation level

    class SerializableUserManager(models.Manager):
        def get_queryset(self):
            return super(SerializableUserManager, self).get_queryset().using('serializable')
    
Swaraj answered 1/6, 2016 at 7:38 Comment(2)
Acceptable. Thank you.Paulettepauley
One gotcha to keep in mind with such a solution is that one connection won't see any changes made by the other connection if those are made in a transaction and that transaction hasn't committed yet.Trabue

© 2022 - 2024 — McMap. All rights reserved.