Django: atomic(): Force transaction, raise AssertionError 如果已经在事务中

Django: atomic(): Force transaction, raise AssertionError if already inside a transaction

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

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

对于某些方法(在 request/response 周期外调用)我需要确定该方法是在一个事务中执行的。我必须强制耐用。 atomic() 如果已经在事务中,将静默使用保存点。

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

atomic() 的关键字参数 savepoint 在这里没有帮助。如果您使用 savepoint=False atomic() 如果已经在事务中,则什么都不做(根据文档)。

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

不幸的是,旧的 is_managed() 已被弃用,没有替代品。

如何创建 atomic_raise_exception_if_already_in_transaction() 装饰器?

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

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

如果您只使用 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
>>>