【问题标题】:Django on MySQL: how to enable autocommit?MySQL 上的 Django:如何启用自动提交?
【发布时间】:2011-06-29 02:54:32
【问题描述】:

我有类似下面的代码在后台进程中运行:

def run()
    while True:
        objs = MyModel.objects.filter(last_updated < time.time() - FREQUENCY)
        print objs

def update()
    while True:
       # some processing code
       mymodel.last_updated = time.time()
       mymodel.save()

上述函数在两个单独的线程中运行:update() 依次更新所有模型,而 run() 选择需要更新的模型。这一切都针对 MySQL 运行,而 MyModel 存在于 InnoDB 表中。

问题是 run() 总是看到 last_updated 的相同值。原因是它在事务内部并选择数据的一致快照。自然,我希望它选择最新的数据。如果我执行以下操作,它会起作用:

def run()
    from django.db import connection
    while True:
        connection.connection.execute('SET autocommit = 1')
        objs = MyModel.objects.filter(last_updated < time.time() - FREQUENCY)
        print objs

但这意味着我每次都会执行一个额外的查询。最重要的是,如果在我设置 autocommit = 1 和以下选择之间的连接关闭,它将无法正常工作。

Postgres 很高兴地支持这一点:http://docs.djangoproject.com/en/dev/ref/databases/#autocommit-mode(至少根据文档),但是有没有办法为 MySQL 启用自动提交?

此外,由于它作为后台进程运行,因此不处理任何请求,也不涉及中间件。

【问题讨论】:

    标签: mysql django django-models transactions


    【解决方案1】:

    在 Django 中,我监听 connection_created 信号,一旦建立连接就发送“set autocommit=1”语句。效果很好!

    from django.db.backends.signals import connection_created
    from django.dispatch import receiver
    
    @receiver(connection_created)
    def connection_init(sender, connection, **kwargv):
        connection.cursor().execute("SET autocommit=1")
    

    【讨论】:

      【解决方案2】:

      我使用的解决方案基本上是在循环结束时运行提交。据我所知,Django 只是不支持这个选项,所以没有办法只禁用自动提交。

      【讨论】:

        【解决方案3】:

        您可以查看事务隔离级别(未提交读取、已提交读取、可重复读取、可序列化)。

        另外,你不应该调整 Django ORM 背后的连接,而是use the dedicated methods for that

        【讨论】:

          猜你喜欢
          • 2010-11-29
          • 1970-01-01
          • 1970-01-01
          • 2011-01-17
          • 1970-01-01
          • 1970-01-01
          • 2013-04-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多