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

4

我在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()装饰器?
2个回答

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

1
检测数据库连接上是否有事务正在运行取决于您的数据库后端库的行为。例如,对于postgresql,psycopg2在提交新查询时会隐式启动一个新的事务,除非已经完成了先前的事务并且未开启显式自动提交模式。在前一种情况下,所有查询都将在事务内运行,因此您没有可靠的检查方法,除非提交当前事务。
另一方面,您可以检测是否有atomic块处于活动状态,请参见docs。您可以使用connection.in_atomic_block属性来检查是否已激活任何atomic块。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接