Пулы соединений с БД ==================== :term:`Сервер приложений ` подключается к :term:`БД` через JDBC-соединения. Для управления и оптимизации использования соединений, сервер приложений создаёт пулы соединений. Параметры пулов задаются в :term:`Конфигурации сервера <Конфигурация сервера>`. Каждый пул имеет уникальное имя: предопределённое или заданное в конфигурации. Пул по умолчанию ---------------- Пул соединений общего назначения. Используется выборками, прикладной бизнес логикой, отчётами – если выполняется одно из условий: - не указаны дополнительные пулы. - в результате работы алгоритма выбора пула, на основе свойств пулов и параметров запроса соединения, соединение не было получено из дополнительного пула. **Имя пула:** ``DEFAULT`` – предопределено и не может быть изменено. .. note:: Пул может быть отключен, если в конфигурации определен хотя бы один дополнительный пул. Для отключения пула удалите атрибут :xsd:attr:`` из конфигурации базы данных. Если вы отключили пул по умолчанию, дополнительный пул с минимальным приоритетом должен иметь ``usageRatio == 1``, что бы заменять собой пул по умолчанию. .. seealso:: :xsd:class:`Configuration.Databases.Database` Дополнительные пулы ------------------- Дополнительные пулы общего назначения. Предназначены для уменьшения нагрузки на основную БД: когда запросы на чтение вне транзакции отправляются в БД-реплику. Должны быть подключены к **синхронным** репликам основной БД. Имеют дополнительные опции конфигурации: - :xsd:attr:`acceptPrimary ` - :xsd:attr:`acceptSecondary ` - :xsd:attr:`acceptTxSession ` - :xsd:attr:`acceptNoTxSession ` - :xsd:attr:`priority ` - :xsd:attr:`usageRatio ` .. seealso:: :xsd:class:`Configuration.Databases.Database.ExtraConnectionPools` Специальные пулы ---------------- Пулы специального назначения могут быть подключены к асинхронным репликам основной БД, предназначенных для формирования агрегированных отчетов за прошлый день/неделю/месяц или иных задач не требующих On-Line данных. Обращение к специальному пулу возможно только по имени. .. seealso:: :xsd:class:`Configuration.Databases.Database.SpecialConnectionPools` Алгоритм выбора пула ----------------------- Если в конфигурации сервера определены дополнительные и/или специализированные пулы, при запросе соединения с БД сервер приложений выбирает подходящий пул на основе параметров запроса и конфигурации пулов. Определение параметров запроса соединения ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Получение соединения может произойти: - Неявно, при: заполнении выборки данными, построении отчёта, ORM-запросах и т.п. действиях – параметры запроса получаются из метаданных или используются значения по умолчанию. - Вызовом :java:meth:`CoreDatabase.getConnection()` без параметров – используются значения по умолчанию. - Вызовом :java:meth:`CoreDatabase.getConnection(Map)` с параметрами. Параметры запроса пула (``RequestOptions``) могут содержать: - ``name`` – имя пула. - ``purpose`` – назначение. Допустимые значения: :java:field:`READ `, :java:field:`READ_WRITE `. - ``isNestedRequest`` – флаг, указывающий на факт получения потоком вторичного/вложенного соединения (второго, третьего и т.д). Определяется автоматически из данных потокового контекста :java:type:`ru.bitec.gtk.core.session.JdbcContext`. Если параметры запроса не указаны, используется значение ``purpose`` по умолчанию: ``READ_WRITE``. Если указан ``name`` ^^^^^^^^^^^^^^^^^^^^ - Поиск выполняется среди всех пулов решения (по умолчанию, дополнительных и специальных). - При отсутствии пула с указанным именем выбрасывается ошибка. Если указан ``purpose`` ^^^^^^^^^^^^^^^^^^^^^^^ Выбирается один из пулов по умолчанию/дополнительных. Формирование ключа выбора """"""""""""""""""""""""" Для каждой комбинации ``purpose`` и ``isNestedRequest`` формируется ключ выбора: - **Тип запроса**: - ``Pri`` – первичный. - ``Sec`` – вторичный/вложенный. - **Назначение соединения**: - ``Tx`` – операция чтения и записи (транзакционная), соответствует ``READ_WRITE``. - ``NoTx`` – операция только чтения (вне транзакции), соответствует ``READ``. Возможные значения ключей: - ``PriTx``: ``acceptPrimary=true``, ``acceptSecondary=false``, ``acceptTxSession=true``, ``acceptNoTxSession=false``. - ``PriNoTx``: ``acceptPrimary=true``, ``acceptSecondary=false``, ``acceptTxSession=false``, ``acceptNoTxSession=true``. - ``SecTx``: ``acceptPrimary=false``, ``acceptSecondary=true``, ``acceptTxSession=true``, ``acceptNoTxSession=false``. - ``SecNoTx``: ``acceptPrimary=false``, ``acceptSecondary=true``, ``acceptTxSession=false``, ``acceptNoTxSession=true``. Формирование списка кандидатов """""""""""""""""""""""""""""" Из всех дополнительных пулов отбираются те, которые удовлетворяют обоим условиям: 1. **Совпадение по типу запроса** - Для первичных запросов: ``acceptPrimary = true``. - Для вторичных запросов: ``acceptSecondary = true``. 2. **Совпадение по назначению** - Для транзакционных операций (``Tx``): ``acceptTxSession = true``. - Для нетранзакционных операций (``NoTx``): ``acceptNoTxSession = true``. Пул по умолчанию не участвует в фильтрации и всегда доступен как запасной вариант (если не отключен). Сортировка по ``priority`` """""""""""""""""""""""""" Отфильтрованные пулы сортируются по убыванию значения атрибута ``priority``. Пул с большим приоритетом рассматривается первым. Пул по умолчанию имеет минимальный приоритет и всегда находится в конце очереди. Выбор на основе ``usageRatio`` """""""""""""""""""""""""""""" Для каждого пула в отсортированном списке: 1. Генерируется случайное число ``random`` в диапазоне ``[0.0, 1.0)``. 2. Если ``usageRatio >= random``, пул выбирается для получения соединения. 3. Если условие не выполнено, проверяется следующий пул в очереди. Параметр ``usageRatio`` (диапазон: ``0.0`` .. ``1.0``) определяет долю запросов, которую должен обрабатывать данный пул: - ``usageRatio = 1.0`` – пул принимает 100% подходящих запросов. - ``usageRatio = 0.5`` – пул принимает примерно 50% подходящих запросов. - ``usageRatio = 0.0`` – пул фактически исключён из ротации. Если пул не выбран """"""""""""""""""""" Если ни один кандидат не выбран, выбрасывается ошибка ``UnableToSelectDataSource``