在Django中为单个事务启用脏读

在Django中为单个事务启用脏读,django,transactions,task,Django,Transactions,Task,我正在Django中构建一个RESTAPI,用户可以在其中为对象运行任务。我在下面创建了一个简单的示例,在这个示例中,我使用事务轻松回滚对象的状态,以防任务失败 from django.db import IntegrityError, transaction def send_object(id): obj = MyModel.objects.get(pk=id) if obj.state != 'Created': raise ValueError('Obj

我正在Django中构建一个RESTAPI,用户可以在其中为对象运行任务。我在下面创建了一个简单的示例,在这个示例中,我使用事务轻松回滚对象的状态,以防任务失败

from django.db import IntegrityError, transaction

def send_object(id):
    obj = MyModel.objects.get(pk=id)
    if obj.state != 'Created':
        raise ValueError('Object not in state "Created"')
    with transaction.atomic():
        obj.state = 'Sending'
        obj.save()

        # send the object...

        obj.state = 'Sent'
        obj.save()
现在,我希望在任务运行时,用户可以通过API看到对象的状态。由于在任务完成之前不会提交事务,因此用户只能看到任务前后的当前状态

我需要某种类型的事务,以防任务期间发生系统故障/关机,并且对象在“发送”时卡住。必须重置状态,以便可以轻松重试任务

隔离级别设置为
READ COMMITTED
,如果不更新代码的其他部分,则无法更改隔离级别

我是否可以在提交事务(即启用脏读)之前仅对此事务使新状态可用?或者我还能做些什么?

基于和,您可以尝试使用两个具有不同隔离级别的数据库连接

以下代码来自链接的答案:

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

您可以根据需要更改它(可能使用
readuncommitted
而不是
SERIALIZABLE
),然后让我们知道这是否解决了您的问题。

无法使用
SERIALIZABLE
readuncommitted
效果很好!在Django 1.11和MariaDB 10.2.13中测试