【问题标题】:Multi-DB Transactions多数据库事务
【发布时间】:2017-01-26 04:16:47
【问题描述】:

带有 Postgres 9.6.1 的 Django 版本 1.10.5

去年我一直在多模式默认数据库环境中工作。但是事情开始发展到我决定将单个数据库拆分为 3 个数据库的地步。

我已经为所有 3 个数据库使用主/从路由器。

我没有使用“默认”数据库密钥。相反,我有“db1”、“db2”和“db3”

我感到困惑的部分是这个多数据库环境中的事务。

在此示例中,它按预期失败。当然是因为没有使用@transaction.atomic(using='db1'),这对我来说很清楚。

@transaction.atomic()
def edit(self, context):
    """Edit

    :param dict context: Context

    :return: None
    """

    # Check if employee exists
    try:
        result = Passport.objects.get(pk=self.user.employee_id)
    except Passport.DoesNotExist:
        return False

    result.name = context.get('name')

    result.save()

但是我有这个奇怪的例子,只是因为我试图理解......我本以为这会失败,但它没有:

@transaction.atomic(using='db1')
def edit(self, context):
    """Edit

    :param dict context: Context

    :return: None
    """

    # Check if employee exists
    try:
        result = Passport.objects.get(pk=self.user.employee_id)
    except Passport.DoesNotExist:
        return False

    result.name = context.get('name')

    with transaction.atomic(using='db2'):
        result.save()

Passport 模型在 DB2 模型中根本不存在。

我的路由器已设置好,以便所有写入都发送到每个受尊重的数据库。

那么在原子事务中设置using='db1'的目的是什么?我查看了源代码,发现它在不“使用”时默认为default

在上面的示例中,我什至在初始事务中进行了另一个事务,但这次using='db2' 甚至不存在模型。我认为这会失败,但事实并非如此,并且数据已写入正确的数据库。

我提出这个问题是因为在某些情况下我需要与所有 3 个数据库进行交互,如果在写入所有 3 个数据库时出现一个问题,则需要回滚所有 3 个数据库,或者如果一切都成功,则提交当然。

也许有人可以帮我解释一下,以便我理解?

【问题讨论】:

  • 整个练习似乎基于错误的前提,即 postgresql 无法处理大量数据。它可以。而且它可以做得比任何其他开源数据库都好得多
  • 事实上我拆分这些是因为在主/从环境中的复制。 3 个数据库中有 2 个根本不需要复制。因此,为了帮助消除未来的压力,我将多模式拆分为多数据库
  • 听起来很合理,但我想知道这是否仍然值得努力。除非你的主从是很远的一部分,否则复制不需要的东西的成本(金钱和计算)将可以忽略不计。

标签: django postgresql django-models transactions


【解决方案1】:

您将 transaction.atomic(using='X') 解释为:在 X 上的事务内运行以下数据库命令

实际上,它只是意味着:在数据库 X 上打开一个事务,然后要么提交它,要么在块的末尾回滚它

或者,正如documentation 所说:

在底层,Django 的事务管理代码:

  • 进入最外层原子块时打开事务;
  • 退出最外层块时提交或回滚事务。

给定命令使用哪个数据库的问题取决于您的router,而不是using 子句。所以你的transaction.atomic(using='db2') 块是没有意义的(它只会在db2 上打开一个事务然后关闭它),但不是错误。

【讨论】:

  • 感谢您的分解。或多或少,我只是在想情况。即使在阅读了这么多文件之后,它也从来没有 100% 清楚,但是这很有帮助,这就是我想要的。
  • 我也遇到了这个问题,文档似乎暗示 using 参数的用法与 Django 其他地方的用法相同,感谢您的回答。
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多