【问题标题】:Django: atomic(): Force transaction, raise AssertionError if already inside a transactionDjango:atomic():强制事务,如果已经在事务中,则引发 AssertionError
【发布时间】:2015-04-04 23:38:27
【问题描述】:

我对 Django 中的 atomic() 有疑问:

https://docs.djangoproject.com/en/1.7/topics/db/transactions/#django.db.transaction.atomic

对于某些方法(称为外部请求/响应周期),我需要确定该方法在一个事务中执行。我必须强制耐久。 atomic() 如果已经在事务中,将静默使用保存点。

记住:ACID http://en.wikipedia.org/wiki/ACID

  • 原子性
  • 一致性
  • 隔离
  • 耐用性

atomic() 的关键字参数 savepoint 在这里没有帮助。如果您使用 savepoint=False atomic() 如果已经在事务中,则不执行任何操作(根据文档)。

如果事务已经在运行,我需要一个异常。

很遗憾,旧的 is_managed() 已被弃用,没有替代品。

如何创建atomic_raise_exception_if_already_in_transaction() 装饰器?

【问题讨论】:

    标签: python django database transactions


    【解决方案1】:

    如果您只使用atomic(),那么您可以检查连接的in_atomic_block 属性:

    >>> from django.db import transaction
    >>> transaction.get_connection().in_atomic_block
    False
    >>> with transaction.atomic():
    ...     print transaction.get_connection().in_atomic_block
    ... 
    True
    >>> transaction.get_connection().in_atomic_block
    False
    >>> 
    

    【讨论】:

      【解决方案2】:

      检测数据库连接上是否有事务运行取决于数据库后端库的行为。例如。 psycopg2 for postgresql 在前一个事务完成后提交新查询时会隐式启动一个新事务,除非已打开显式自动提交模式。在前一种情况下,所有查询都将在事务中运行,因此除了提交当前事务之外,您没有任何可靠的检查。

      另一方面,您可以检测是否存在活动的atomic 块,请参阅docs。您可以使用connection.in_atomic_block 属性来检查是否有任何atomic 块被激活。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-08
        • 1970-01-01
        • 1970-01-01
        • 2021-12-24
        • 2014-01-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多