【问题标题】:Django queryset.count() causes dirty transactionDjango queryset.count() 导致脏事务
【发布时间】:2014-07-14 17:59:28
【问题描述】:

我的一个测试函数(用@transaction.commit_manually 装饰)出现意外错误:

TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK

我追踪到了这段代码:

print 'step 1, dirty = %s' % transaction.is_dirty()
query_set = Foo.objects.filter(name='leeroy')
print 'step 2, dirty = %s' % transaction.is_dirty()
n = query_set.count()
print 'step 3, dirty = %s' % transaction.is_dirty()

输出是这样的:

step 1, dirty = False
step 2, dirty = False
step 3, dirty = True

为什么调用 count() 会将事务标记为脏?

【问题讨论】:

    标签: django transactions django-queryset


    【解决方案1】:

    原因是事务在当前版本的 django 中的任何查询上都被标记为脏(脏意味着连接的事务正在进行中)。 django 的早期版本不会将事务标记为脏,除非发出 data modifyin 查询 - 但由于这种方式有些混乱,所以更改了,更重要的是 django 不知道在使用原始 SQL 时哪些查询是数据修改。

    filter() 调用不会打开事务,因为此时未执行查询。

    如果可以,请使用 transaction.atomic - 它易于使用并且在几乎所有情况下都能做正确的事情。

    【讨论】:

      猜你喜欢
      • 2018-12-13
      • 1970-01-01
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 2021-07-16
      • 1970-01-01
      • 2010-09-21
      相关资源
      最近更新 更多