关于MySQL的Django:如何启用自动提交?

时间:2011-02-17 13:46:19

标签: mysql django django-models transactions

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

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和下面的select之间关闭,它将无法工作。

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

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

3 个答案:

答案 0 :(得分:5)

在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")

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以查看事务隔离级别(Read uncommitted,Read committed,Repeatable read,Serializable)。

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