Версия: entity 5.4.0.0, КоннекторPostgreSQL, OneScript 2.2.0.
После перезапуска PostgreSQL менеджер сущностей больше не работает: соединение, разорванное сервером, остается в пуле и выдается снова, и каждая следующая операция падает с Connection is not open, хотя база уже доступна. Восстанавливается только перезапуском процесса.
Воспроизведение, сущность:
&Идентификатор
&ГенерируемоеЗначение
&Колонка(Тип = "Целое")
Перем Идентификатор Экспорт;
&Колонка
Перем Текст Экспорт;
&Сущность(ИмяТаблицы = "Записи")
Процедура ПриСозданииОбъекта()
КонецПроцедуры
Сценарий: раз в 2 секунды сохраняет запись, на девятой секунде PostgreSQL перезапускается (docker restart):
#Использовать entity
ПодключитьСценарий(ОбъединитьПути(ТекущийКаталог(), "Запись.os"), "Запись");
СтрокаСоединения = "Host=psql;Username=postgres;Password=postgres;Database=postgres;port=5432;";
ИсточникДанных = Новый ИсточникДанных("Основной", Тип("КоннекторPostgreSQL"), СтрокаСоединения, Новый Массив, 10);
МенеджерСущностей = Новый МенеджерСущностей(ИсточникДанных);
МенеджерСущностей.ДобавитьКлассВМодель(Тип("Запись"));
МенеджерСущностей.Инициализировать();
Для Номер = 1 По 20 Цикл
Попытка
Запись = Новый Запись();
Запись.Текст = "попытка " + Номер;
МенеджерСущностей.Сохранить(Запись);
Сообщить(СтрШаблон("%1: записано, всего %2", Номер, МенеджерСущностей.Получить(Тип("Запись")).Количество()));
Исключение
Сообщить(СтрШаблон("%1: %2", Номер, КраткоеПредставлениеОшибки(ИнформацияОбОшибке())));
КонецПопытки;
Приостановить(2000);
КонецЦикла;
1: записано, всего 1
2: записано, всего 2
3: записано, всего 3
4: Внешнее исключение (Npgsql.PostgresException): 57P01: terminating connection due to administrator command
5: Внешнее исключение (System.InvalidOperationException): Connection is not open
6: Внешнее исключение (System.InvalidOperationException): Connection is not open
...
20: Внешнее исключение (System.InvalidOperationException): Connection is not open
База отвечает уже к пятой попытке, но все следующие операции идут через то же закрытое соединение.
Причина, насколько видно по internal/Классы/ПулСоединенийСБД.os: ВзятьСвободное выдает соединение из очереди свободных, не проверяя Открыт() коннектора, а ВернутьВПул закрывает и заменяет только соединение с незавершенной транзакцией (Испорчено()). Соединение, закрытое сервером, возвращается в пул как исправное. Кроме того, соединение закрепляется за потоком исполнения, и долгоживущий поток, например фоновое задание приложения, держит испорченное соединение до своего завершения.
В приложении на autumn-data это выглядит так: после перезапуска базы и фоновые задания, и обработчики HTTP-запросов падают до перезапуска процесса.
Как вариант исправления: при выдаче соединения из пула и при использовании закрепленного соединения проверять Открыт() и заменять закрытое соединение новым, а ошибку соединения (закрытое соединение, 57P01 и подобные) считать порчей соединения, чтобы ВернутьВПул его закрыл.
Версия: entity 5.4.0.0, КоннекторPostgreSQL, OneScript 2.2.0.
После перезапуска PostgreSQL менеджер сущностей больше не работает: соединение, разорванное сервером, остается в пуле и выдается снова, и каждая следующая операция падает с
Connection is not open, хотя база уже доступна. Восстанавливается только перезапуском процесса.Воспроизведение, сущность:
Сценарий: раз в 2 секунды сохраняет запись, на девятой секунде PostgreSQL перезапускается (
docker restart):База отвечает уже к пятой попытке, но все следующие операции идут через то же закрытое соединение.
Причина, насколько видно по
internal/Классы/ПулСоединенийСБД.os:ВзятьСвободноевыдает соединение из очереди свободных, не проверяяОткрыт()коннектора, аВернутьВПулзакрывает и заменяет только соединение с незавершенной транзакцией (Испорчено()). Соединение, закрытое сервером, возвращается в пул как исправное. Кроме того, соединение закрепляется за потоком исполнения, и долгоживущий поток, например фоновое задание приложения, держит испорченное соединение до своего завершения.В приложении на autumn-data это выглядит так: после перезапуска базы и фоновые задания, и обработчики HTTP-запросов падают до перезапуска процесса.
Как вариант исправления: при выдаче соединения из пула и при использовании закрепленного соединения проверять
Открыт()и заменять закрытое соединение новым, а ошибку соединения (закрытое соединение,57P01и подобные) считать порчей соединения, чтобыВернутьВПулего закрыл.