Postgres: Проблема с уже закрытым соединением
Я сталкиваюсь с ошибкой "соединение уже закрыто" в моем Django-приложении, которое использует PostgreSQL в качестве бэкенда базы данных. Несмотря на то, что я пробовал различные решения, я не могу решить эту проблему.
Фоновая информация:
Django
4.2.13psycopg2
2.9.9
Заявление о проблеме
У меня есть Django-приложение, которое периодически выдает ошибку "соединение уже закрыто" при попытке взаимодействия с базой данных PostgreSQL. Эта проблема часто возникает при следующих обстоятельствах:
Запуск фоновой задачи для вставки данных в базу данных каждые 30 секунд
errors: File "django\utils\asyncio.py", line 26, in innerreturn func(*args, **kwargs)
File "django\db\backends\base\base.py", line 330, in cursorreturn self._cursor()
File "django\db\backends\base\base.py", line 308, in _cursorreturn self._prepare_cursor(self.create_cursor(name))
File "django\db\utils.py", line 91, in exitraise dj_exc_value.with_traceback(traceback) from exc_value
File "django\db\backends\base\base.py", line 308, in _cursorreturn self._prepare_cursor(self.create_cursor(name))
File "django\utils\asyncio.py", line 26, in innerreturn func(*args, **kwargs)
File "django\db\backends\postgresql\base.py", line 330, in create_cursorcursor =
self.connection.cursor()django.db.utils.InterfaceError: connection already closed
Что я пробовал
- Убедитесь, что параметры подключения к базе данных верны.
- Проверили, нет ли долго выполняющихся запросов, которые могут вызывать таймауты.
- Настроил параметры подключения к базе данных Django, такие как
CONN_MAX_AGE
иCONN_HEALTH_CHECKS
. - Увеличили настройки таймаута соединения в PostgreSQL.
Несмотря на эти попытки, проблема сохраняется.
CONN_HEALTH_CHECKS
работает только в контексте (HTTP) запроса. Она ничего не делает, если используется в фоновой задаче:
Если установлено значение True, существующие постоянные соединения с базой данных будут проверяться на работоспособность перед повторным использованием в каждом запросе, выполняющем доступ к базе данных.
Это известная проблема.
Вы должны выполнять аналогичную проверку вручную в своем цикле. Мы не видим ваш реальный код, но он будет похож на следующий:
from django.db import close_old_connections
while True:
close_old_connections()
# ...do the things ...
time.sleep(30)