Django / postgres事务隔离级别设置被忽略

时间:2018-05-30 15:41:32

标签: django postgresql

我在设置事务隔离级别时遇到问题。我想要最严格的serializable,而默认是read committed。

我正在使用:

Django==1.10.6
psycopg2==2.5.1

在heroku上运行。

基于文档: https://docs.djangoproject.com/en/1.10/ref/databases/#isolation-level

我有以下settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'OPTIONS': {
        'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE,
    }
}

if on_heroku:
    DATABASES['default'] = dj_database_url.config()

这是视图代码:

@require_http_methods(["POST"])
@transaction.atomic
@login_required()
def api_test_add_one(request):
    cursor = connection.cursor()

    cursor.execute('SHOW default_transaction_isolation')

    logger.info("aa: " + str(cursor.fetchone()))

    return HttpResponse("{}", content_type="application/json")

输出结果为:

aa: (u'read committed',)

我在同时访问同一个端点时运行了不同的测试,在DB中递增一个整数并确认事务没有被隔离。

1 个答案:

答案 0 :(得分:3)

OPTIONS属于里面数据库的设置,例如

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgres',
        ...
        'OPTIONS': {
            'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE,
        },
    },
}

在您的情况下,您替换DATABASES['default'],因此您的OPTIONS设置将会丢失:

if on_heroku:
    DATABASES['default'] = dj_database_url.config()

相反,您可以在设置OPTIONS后设置DATABASES['default']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
}

if on_heroku:
    DATABASES['default'] = dj_database_url.config()
    DATABASES['default']['OPTIONS'] = {
        'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE,
    }