При написании много-сервисной системы в корой каждый сервис должен быть многопоточен, столкнулись с проблемой использования подключения к базе данных. Сервисы разрабатываются на QT, поэтому использовали модуль QtSql для взаимодействие с БД.
Проблемы
- Для каждого потока необходимо свое собственное подключение к БД (QSqlDatabase). При использовании одного подключения из разных потоков возникаем ошибка сегментирования.
- Т.к. в текущий момент времени возможно держать открытыми ограниченное число подключений к БД, необходимо реализовать захват, освобождение и ожидание подключения потоками.
- В контексте потока, для правильной работы с транзакциями необходимо работать только с одним подключением. Например: Сущность заказ содержит в себе сущности Товар. При сохранении Заказа должны сохранится все товары. Если при сохранении товара возникает исключительная ситуация, то вся транзакция по сохранению заказ должна отменится.
- Библиотека должна уметь работать с несколькими БД одновременно, причем разных типов (Mysql,PostgreSQL)
Решение
В итоге у нас получилось 3 класса:
- Connection — класс обертка отвечающий за работу с БД: Подключение, выполнение и обработка результатов запросов.
- ConnectionManager — синглтон хоронящий в себе подключени и отвечает за выдачу и освобождение подключений.
- ManagedConnection — класс обертка для автоматизации захвата и освобождения подключения.