在Django中启用对单个事务的脏读取

时间:2018-07-04 22:13:07

标签: django transactions task

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

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,在不更新代码其他部分的情况下无法更改。

我是否可以在仅为此事务提交事务(即启用脏读)之前使新状态可用?还是我还能做些其他事情?

1 个答案:

答案 0 :(得分:2)

基于this similar questioncomments to this answer,您可以尝试使用两个具有不同隔离级别的数据库conexions。

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

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,
        },
    },
}

您可以根据需要进行更改(可以使用READ UNCOMMITED代替SERIALIZABLE),然后告诉我们是否可以解决您的问题。