Django:atomic():强制事务,如果已经在事务中,则引发AssertionError

时间:2015-02-05 07:33:32

标签: python django database transactions

我在Django中遇到atomic()的问题:

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

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

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

  • 原子性
  • 一致性
  • 分离
  • 耐久性< ---那就是我想强迫的。

savepoint的关键字参数atomic()在这里没有帮助。如果您使用savepoint = False,则atomic()默认情况下(根据文档),如果已经在事务中,则默认无效。

如果已经是一个正在运行的事务,我需要一个例外。

不幸的是旧的is_managed()已弃用而没有替换。

如何创建atomic_raise_exception_if_already_in_transaction()装饰器?

2 个答案:

答案 0 :(得分:1)

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

另一方面,您可以检测是否有atomic块处于活动状态,请参阅docs。您可以使用connection.in_atomic_block属性来检查是否已激活任何atomic块。

答案 1 :(得分: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
>>>