【问题标题】:Rollback all Django db transactions with middleware使用中间件回滚所有 Django 数据库事务
【发布时间】:2016-10-10 17:56:25
【问题描述】:

我们正在将我们的一个主要 django 网站从 1.4 升级到 1.9。我想pull a github 并使用laboratory 来针对现有生产站点测试升级站点。但是,出于显而易见的原因,我不能让新站点写入(postgres)生产数据库。

现在,我可能会给这个只读实例 readonly db 权限,但我不能让它在每次写入时都出错。似乎我应该能够将有问题的数据库连接设置为使用ATOMIC_REQUESTS = True,然后编写中间件以在每个请求结束时回滚事务,但是自 1.4 以来 Django 的事务处理发生了很大变化,以至于我我不太确定实现该中间件的最佳方法。

无论如何,我如何编写中间件以可靠地回滚每个事务?

【问题讨论】:

    标签: django transactions


    【解决方案1】:

    正确的做法是设置AUTOCOMMIT=False而不是设置ATOMIC_REQUESTS = True

    您可以完全禁用给定的 Django 事务管理 数据库通过在其配置中将 AUTOCOMMIT 设置为 False。如果你 这样做,Django 不会启用自动提交,也不会执行任何操作 提交。您将获得底层数据库的常规行为 图书馆。 这要求您明确提交每个事务,即使是由 Django 或第三方库启动的事务。因此,这是 最好用于您想要自己运行的情况 事务控制中间件或做一些非常奇怪的事情。

    因此,除非您提交所有内容,否则实际上不会有任何内容进入数据库。如果您使用数据库支持的会话,您将需要在那里进行手动提交,但保留其他所有内容。这样可以避免实时服务器中的任何数据被修改。

    AUTOCOMMIT=False 进入 settings.py 如下:

    DATABASE = {
       'default': { /* other stuff */,
             AUTOCOMMIT: False,
        }
    }
    

    此方法不涉及创建任何自定义中间件。它可以很容易地打开和关闭。

    【讨论】:

    • 太棒了。我会试试看。但是有一个问题:如果我不回滚事务并且不提交它们,那么既然 Django 也有持久连接,我是否需要担心它们堆积起来?
    • 那个我真的不知道,但出于测试目的,因为您没有进行数千次交易,我认为这并不重要。顺便说一句,您不必手动回滚。
    • 我还没有找到它——其他优先事项出现了。 :) 试过后我会回来查看的。此时可能在几周内。
    • 一个后续问题:如果我在我的应用程序的任何地方使用任何手动事务管理(例如@transaction.commit_on_success),这仍然有效吗?好像不会。
    猜你喜欢
    • 1970-01-01
    • 2018-05-26
    • 2016-08-10
    • 2023-04-07
    • 2020-06-05
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多