Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Per-transaction isolation level in Django ORM

Tags:

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
like image 457
Pavel Patrin Avatar asked Dec 09 '14 19:12

Pavel Patrin


People also ask

What is default isolation level in transaction?

Transaction Isolation Levels The default isolation level is REPEATABLE READ . Other permitted values are READ COMMITTED , READ UNCOMMITTED , and SERIALIZABLE .

Can different transactions have different isolation levels?

SET TRANSACTION ISOLATION LEVEL affects the connection it's called on. It specifies what this connection will tolerate, what locking strategies this connection will use, etc. If another connection uses a different isolation level, both levels are "in effect" at the same time, for their respective connections.

How do you calculate current transaction isolation level?

By executing SELECT @@TX_ISOLATION command we can check the current MySQL transaction isolation level.

What is transactional isolation?

Transaction isolation levels are a measure of the extent to which transaction isolation succeeds. In particular, transaction isolation levels are defined by the presence or absence of the following phenomena: Dirty Reads A dirty read occurs when a transaction reads data that has not yet been committed.


1 Answers

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')
    
like image 195
dhui Avatar answered Sep 17 '22 12:09

dhui