Потоковая задача Django автоматически не обрабатывает соединения дб или транзакции?

Протокол =, как связаться, Портируйте =, куда связаться

56
задан Gabriel Hurley 20 August 2009 в 02:26
поделиться

1 ответ

После нескольких недель тестирования и чтения исходного кода Django я нашел ответ на свой вопрос:

Транзакции

Поведение Django по умолчанию для автоматической фиксации остается верным для моя поточная функция. Однако в документации Django говорится:

Как только вы выполняете действие, требующее записи в базу данных, Django создает операторы INSERT / UPDATE / DELETE, а затем выполняет COMMIT. Здесь нет неявного ROLLBACK.

Последнее предложение очень буквальное. Он НЕ ВЫДАЕТ команду ROLLBACK, если что-то в Django не установило грязный флаг. Поскольку моя функция выполняла только операторы SELECT, она никогда не устанавливала грязный флаг и не запускала COMMIT.

Это противоречит тому факту, что PostgreSQL считает, что транзакция требует ROLLBACK, потому что Django выдал команду SET для часового пояса. При просмотре журналов я бросил себя, потому что продолжал видеть эти операторы ROLLBACK и предполагал, что их источником является управление транзакциями Django. Оказывается, это не так, и это нормально.

Connections

Управление подключением - вот где все действительно усложняется. Оказывается, Django использует signal.request_finished.connect (close_connection) , чтобы закрыть обычно используемое соединение с базой данных. Поскольку в Django обычно не происходит ничего, что не связано с запросом, вы принимаете такое поведение как должное.

В моем случае, однако, не было запроса, потому что задание было запланировано. Нет запроса - значит нет сигнала. Отсутствие сигнала означает, что соединение с базой данных никогда не было закрыто.

Возвращаясь к транзакциям, оказывается, что это просто вызов соединения. close () при отсутствии каких-либо изменений в управлении транзакциями выдает оператор ROLLBACK в журнале PostgreSQL, который я искал.

Решение

Решение состоит в том, чтобы позволить обычному управлению транзакциями Django действуйте как обычно и просто закройте соединение одним из трех способов:

  1. Напишите декоратор, который закрывает соединение, и заключите в него необходимые функции.
  2. Перехватите существующие сигналы запроса, чтобы Django закрыл соединение.
  3. ] Закройте соединение вручную в конце функции.

Любой из этих трех будет (и будет работать).

Это сводит меня с ума на несколько недель. Надеюсь, это поможет кому-то еще в будущем!

Решение

Решение состоит в том, чтобы позволить нормальному управлению транзакциями Django работать как обычно, и просто закрыть соединение одним из трех способов:

  1. Напишите декоратор, который закрывает соединение, и оберните в него необходимые функции.
  2. Подключитесь к существующим сигналам запроса, чтобы Django закрыл соединение.
  3. Закройте соединение вручную в конце функции.

Любой из этих трех будет (и будет работать).

Это сработало. я схожу с ума неделями. Надеюсь, это поможет кому-то еще в будущем!

Решение

Решение состоит в том, чтобы позволить нормальному управлению транзакциями Django работать в обычном режиме и просто закрыть соединение одним из трех способов:

  1. Напишите декоратор, который закрывает соединение, и оберните в него необходимые функции.
  2. Подключите существующие сигналы запроса, чтобы Django закрыл соединение.
  3. Закройте соединение вручную в конце функции.

Любой из этих трех будет (и будет работать).

Это привело к я сумасшедший неделями. Надеюсь, это поможет кому-то еще в будущем!

Любой из этих трех будет (и будет работать).

Это сводило меня с ума на несколько недель. Надеюсь, это поможет кому-то еще в будущем!

Любой из этих трех будет (и будет работать).

Это сводило меня с ума на несколько недель. Надеюсь, это поможет кому-то еще в будущем!

105
ответ дан 26 November 2019 в 17:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: