为什么这个循环每五秒不显示更新的对象计数?

8 投票
1 回答
1705 浏览
提问于 2025-04-15 19:01

我用这段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的自动提交并不是数据库中的自动提交,它们是完全独立的。不过这超出了这个问题的范围。

编辑于2012年1月22日

这里

撰写回答