我在其中一个测试函数中遇到意外错误(用@ 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()会将事务标记为脏?
答案 0 :(得分:1)
原因是当前版本的django中的任何查询都将事务标记为脏(dirty表示连接的事务正在进行中)。早期版本的django并没有将事务标记为脏,除非发出了数据modifyin查询 - 但是由于这种方式有些混乱,更改了django并不知道在使用原始SQL时哪些查询是数据修改。 / p>
filter()调用不会打开事务,因为此时不执行查询。
如果可以,请使用transaction.atomic - 它很容易使用,并且在所有情况下都做正确的事。