使用多数据库的 Django 事务

kal*_*loc 3 python django django-models django-orm

我有三个数据库,我想根据一个请求在事务中向它们添加数据。

\n\n

例如我的代码。

\n\n
@transaction.commit_manually\ndef my_view(request):\n    try:\n        MyModel_one(...).save(using='default')\n        MyModel_two(...).save(using='db_one')\n        MyModel_three(...).save(using='db_two') # <-- for example we make exception here (duplicate data)\n    except IntegrityError:\n        transaction.rollback()\n        transaction.rollback(using='db_one')\n        transaction.rollback(using='db_two')\n        return ...\n    transaction.commit()\n    transaction.commit(using='db_one')\n    transaction.commit(using='db_two')\n    return ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
    \n
  1. MyModel_one \xe2\x80\x94 数据未保存
  2. \n
  3. MyModel_two \xe2\x80\x94 数据已保存(我不明白为什么)
  4. \n
  5. MyModel_two \xe2\x80\x94 数据未保存,因为希望错误
  6. \n
\n\n

问题:为什么交易在这里不起作用?我该怎么做才能获得工作交易?

\n\n

(我尝试使用其他方法,但没有成功)\n(而且我知道这不是漂亮的代码,但对于理解问题来说非常简单)

\n\n

Django 1.7.7\nPython 2.7

\n\n

数据库:\n默认 \xe2\x80\x94 postgres\ndb_one \xe2\x80\x94 mysql\ndb_two \xe2\x80\x94 mysql

\n

Ala*_*air 7

transaction.commit_manually装饰器在 Django 1.6 中已被弃用。您应该切换到 Django 新的事务管理。

我认为您不需要手动提交事务,您可以嵌套transaction.atomic.

def my_view(request):
    try:
        with transaction.atomic(using='default'):
            with transaction.atomic(using='db_one'):
                with transaction.atomic(using='db_two'):
                    MyModel_one(...).save(using='default')
                    MyModel_two(...).save(using='db_one')
                    MyModel_three(...).save(using='db_two') # raises exception
    except IntegrityError:
        return ...
    return ...
Run Code Online (Sandbox Code Playgroud)