Django на MySQL: как включить автокоммит? - PullRequest
4 голосов
/ 17 февраля 2011

У меня есть что-то вроде следующего кода, который выполняется в фоновом процессе:

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?

Кроме того, поскольку он работает как фоновый процесс, запросы не обрабатываются, и промежуточное программное обеспечение не используется.

Ответы [ 3 ]

5 голосов
/ 15 января 2013

В 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")
0 голосов
/ 15 января 2016

Можно посмотреть на уровень изоляции транзакции (чтение незафиксировано, чтение зафиксировано, повторное чтение, сериализуемо).

Кроме того, вы не должны настраивать соединение за Django ORM, но использовать специальные методы для этого .

0 голосов
/ 02 марта 2011

Решение, которое я использую, в основном заключается в запуске коммита в конце цикла.Насколько я могу судить, Django просто не поддерживает эту опцию, поэтому нет способа просто отключить автокоммит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...