Django queryset.count()导致脏事务

时间:2014-07-14 17:59:29

标签: django transactions django-queryset

我在其中一个测试函数中遇到意外错误(用@ 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()会将事务标记为脏?

1 个答案:

答案 0 :(得分:1)

原因是当前版本的django中的任何查询都将事务标记为脏(dirty表示连接的事务正在进行中)。早期版本的django并没有将事务标记为脏,除非发出了数据modifyin查询 - 但是由于这种方式有些混乱,更改了django并不知道在使用原始SQL时哪些查询是数据修改。 / p>

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

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