Russian Qt Forum
Апрель 27, 2024, 11:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Проверка состояния подключения к БД.  (Прочитано 17950 раз)
ksergey85
Гость
« : Сентябрь 16, 2015, 16:39 »

Пользователи драйвера QODBC, подскажите пожалуйста как вы проверяете состояние коннекта к БД на предмет умерло/не умерло? Не дело ведь это выполнять "SELECT 1" после каждого неудачно выполненного запроса только для того, чтобы проверить не отвалился ли коннект. Или как-то по коду ошибки QSqlError все-таки можно догадаться, что запрос обломался именно по причине отпавшего коннекта.  Непонимающий
Погуглив, нашел только вот что https://bugreports.qt.io/browse/QTBUG-223. Закрыто в 2013. Никаких вразумительных комментариев.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #1 : Сентябрь 16, 2015, 17:58 »

Не знаю что там есть для ODBC, а для postgresql и mysql я в отдельном потоке с заданным интервалом проверяю валидность соединения и при его разрыве посылаю сигнал об этом.
Записан
ksergey85
Гость
« Ответ #2 : Сентябрь 16, 2015, 18:05 »

Не знаю что там есть для ODBC, а для postgresql и mysql я в отдельном потоке с заданным интервалом проверяю валидность соединения и при его разрыве посылаю сигнал об этом.

Как проверяете? Можно кода?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Сентябрь 16, 2015, 18:14 »

Как проверяете? Можно кода?
Кода можно будет только завтра, сейчас смогу только на словах.
Создаем отдельное тестовое подключение, запускаем поток, в котором по таймеру выполняется слот.
В слоте проверяем валидность подключения проверяя открыто ли соединение и пытаясь выполнить запрос "SELECT TRUE", если все нормально - выходим из слота. Иначе посылаем сигнал об отключении базы и пытаемся переподключиться.
Записан
Nidxogg
Гость
« Ответ #4 : Сентябрь 17, 2015, 20:05 »

Цитировать
В слоте проверяем валидность подключения проверяя открыто ли соединение
Если речь про isOpen, то оно true выдает даже после разрыва связи с БД. Разве нет?
Цитировать
и пытаясь выполнить запрос "SELECT TRUE", если все нормально - выходим из слота.
Результат запроса (false) у вас сразу приходит или с таймаутом каким-то?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #5 : Сентябрь 17, 2015, 20:14 »

Если речь про isOpen, то оно true выдает даже после разрыва связи с БД. Разве нет?
Да, поэтому и нужен второй запрос.

Результат запроса (false) у вас сразу приходит или с таймаутом каким-то?
Сразу. Отдельная нитка нужна, что бы попытка переподключения не блокировала основную нить и не морозила UI. Открытие соединения с не отвечающим сервером БД заметно тормозит нить.
Записан
Nidxogg
Гость
« Ответ #6 : Сентябрь 17, 2015, 20:20 »

Понятно, тогда тоже +1 к посмотреть код
(интересует как сама нитка создается и подключение в ней)
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #7 : Сентябрь 17, 2015, 20:24 »

Понятно, тогда тоже +1 к посмотреть код
(интересует как сама нитка создается и подключение в ней)
Если я утром забуду, напишите сообщение в этой теме еще раз (или в личку) - я выложу.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #8 : Сентябрь 18, 2015, 10:23 »

Код
C++ (Qt)
class DbWatcher : public QThread
{
Q_OBJECT
public:
explicit DbWatcher();
explicit DbWatcher( int interval, QSqlDatabase db );
 
int interval() const;
void setInterval( int val );
 
bool isConnected() const;
QSqlDatabase connection() const;
void setConnection( QSqlDatabase db );
 
signals:
void connected();
void disconnected();
 
protected slots:
void reconnect();
 
protected:
virtual void run();
 
int m_interval;
QSqlDatabase m_db;
QTimer *m_timer;
bool m_connOk;
mutable QMutex m_mutex;
};
 

Код
C++ (Qt)
DbWatcher::DbWatcher() :
QThread( 0 ),
m_interval( 0 ),
m_db(),
m_timer( 0 ),
m_connOk( false )
{
moveToThread( this );
}
 
DbWatcher::DbWatcher( int interval, QSqlDatabase db ) :
QThread( 0 ),
m_interval( interval ),
m_db( db ),
m_timer( 0 ),
m_connOk( false )
{
moveToThread( this );
}
 
int DbWatcher::interval() const
{
QMutexLocker lock( &m_mutex );
return m_interval;
}
 
void DbWatcher::setInterval( int val )
{
QMutexLocker lock( &m_mutex );
m_interval = val;
}
 
bool DbWatcher::isConnected() const
{
QMutexLocker lock( &m_mutex );
return m_db.isOpen() && m_db.exec( "SELECT TRUE" ).isActive();
}
 
QSqlDatabase DbWatcher::connection() const
{
QMutexLocker lock( &m_mutex );
return m_db;
}
 
void DbWatcher::setConnection( QSqlDatabase db )
{
QMutexLocker lock( &m_mutex );
m_db = db;
}
 
void DbWatcher::reconnect()
{
Q_ASSERT( m_timer );
 
if( isConnected() )
return;
 
m_timer->stop();
 
if( m_connOk )
{
m_connOk = false;
emit disconnected();
}
 
m_db.open();
 
if( isConnected() )
{
m_connOk = true;
emit connected();
}
 
m_timer->start();
}
 
void DbWatcher::run()
{
m_timer = new QTimer;
connect( m_timer, SIGNAL(timeout()), SLOT(reconnect()) );
m_timer->setSingleShot( false );
m_timer->setInterval( m_interval * 1000 );
m_timer->start();
 
QMetaObject::invokeMethod( this, "reconnect", Qt::QueuedConnection );
 
exec();
 
m_timer->stop();
delete m_timer;
}
 
Записан
Nidxogg
Гость
« Ответ #9 : Сентябрь 18, 2015, 19:09 »

Цитировать
Создаем отдельное тестовое подключение
Имеется ввиду addDatabase?
Судя по вашему коду используется defaultConnection?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #10 : Сентябрь 18, 2015, 19:30 »

Цитировать
Создаем отдельное тестовое подключение
Имеется ввиду addDatabase?
Судя по вашему коду используется defaultConnection?
Нет. Мы передаем соединение, которое будет использоваться для тестирования.
Я создаю рабочее соединение, клонирую его и клон передаю ватчеру для проверки. Для каждого потока нужно отдельное соединение.
Записан
Nidxogg
Гость
« Ответ #11 : Сентябрь 18, 2015, 19:40 »

А если в процессе работы требуется отключиться от БД
Цитировать
void QSqlDatabase::removeDatabase ( const QString & connectionName )
и подключиться с другими параметрами - потребуется ли пересоздать ватчер?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #12 : Сентябрь 18, 2015, 21:00 »

А если в процессе работы требуется отключиться от БД
Цитировать
void QSqlDatabase::removeDatabase ( const QString & connectionName )
и подключиться с другими параметрами - потребуется ли пересоздать ватчер?
Нет. Достаточно будет сделать setConnection с клоном нового подключения.
Записан
Nidxogg
Гость
« Ответ #13 : Сентябрь 18, 2015, 22:37 »

Спасибо за информацию
Записан
Nidxogg
Гость
« Ответ #14 : Декабрь 03, 2015, 20:42 »

del
« Последнее редактирование: Декабрь 31, 2015, 15:42 от Nidxogg » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.104 секунд. Запросов: 22.