为什么这个循环每五秒不显示更新的对象计数?
我用这段Python代码每5秒输出一次“东西”的数量:
def my_count():
while True:
print "Number of Things: %d" % Thing.objects.count()
time.sleep(5)
my_count()
如果在我运行my_count()的时候,其他程序生成了新的“东西”,my_count()依然会打印出之前的数字,即使数据库里的数量已经变了。(不过如果我结束my_count()并重新启动它,它就会显示新的“东西”数量。)
这些“东西”存储在MYSQL的innodb数据库里,而这段代码是在ubuntu系统上运行的。
为什么my_count()不重启就不能显示新的Thing.objects.count()呢?
1 个回答
16
因为Python的数据库API默认是AUTOCOMMIT=OFF模式,并且(至少对于MySQLdb来说)使用的是REPEATABLE READ隔离级别。这意味着在后台你有一个正在进行的数据库事务(InnoDB是一个支持事务的引擎),在这个事务中,第一次访问某一行(或者可能是整个表,我不太确定)会固定这个资源的“视图”,直到事务结束。
为了防止这种情况发生,你需要“刷新”当前的事务:
from django.db import transaction
@transaction.autocommit
def my_count():
while True:
transaction.commit()
print "Number of Things: %d" % Thing.objects.count()
time.sleep(5)
-- 注意,transaction.autocommit装饰器只是用来进入事务管理模式(这也可以通过手动使用transaction.enter_transaction_management/leave_transaction_management函数来完成)。
还有一点需要注意的是,Django的自动提交并不是数据库中的自动提交,它们是完全独立的。不过这超出了这个问题的范围。