我有类似以下代码在后台进程中运行:
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启用自动提交?
此外,由于它作为后台进程运行,因此不会处理任何请求,也不会涉及中间件。
答案 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。