一尘不染

为什么此循环不每五秒钟显示一次更新的对象计数?

mysql

我使用以下python代码每5秒输出事物数:

def my_count():     
    while True:
        print "Number of Things: %d" % Thing.objects.count()
        time.sleep(5)

my_count()

如果在my_count()运行时另一个进程生成了新的Thing,则my_count()将继续打印相同的数字,即使现在它已在数据库中更改了。(但是,如果我杀死my_count()并重新启动它,它将显示新的Thing计数。)

事物存储在MYSQL innodb数据库中,并且此代码在ubuntu上运行。

为什么my_count()不重新启动就不会显示新的Thing.objects.count()?


阅读 264

收藏
2020-05-17

共1个答案

一尘不染

因为Python DB 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_managemen函数手动完成)。

需要注意的另一件事-Django的自动提交与数据库中的自动提交不同,它是完全独立的。但这超出了这个问题的范围。

于22/01/2012修改

是一个类似问题的“双答案”。

2020-05-17