【问题标题】:Enable dirty reads for single transaction in Django在 Django 中为单个事务启用脏读
【发布时间】:2018-12-13 08:16:42
【问题描述】:

我正在 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,如果不更新代码的其他部分,则无法更改。

我可以在事务提交之前为这个事务提供新状态(即启用脏读)吗?或者还有什么我可以做的吗?

【问题讨论】:

    标签: django transactions task


    【解决方案1】:

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

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

    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),然后告诉我们是否可以解决您的问题。

    【讨论】:

    • 无法与SERIALIZABLE 一起使用,但READ UNCOMMITED 效果很好!在 Django 1.11 和 MariaDB 10.2.13 中测试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    • 2015-10-31
    • 1970-01-01
    相关资源
    最近更新 更多