Russian Qt Forum

Qt => Базы данных => Тема начата: MetalKrot от Сентябрь 21, 2012, 15:22



Название: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: MetalKrot от Сентябрь 21, 2012, 15:22
Доброго времени суток.

У меня такая проблема. Есть приложение, которое взаимодействует с базой данных. База должна отправлять NOTIFY всем своим подписчикам (несколько запущенных программ). База не отправляет сообщение тому приложению, чьи действия повлекли возникновение сообщения. Тоесть если приложение изменило данные, то оно не получает сигнал, а все остальные приложения получают. Почему?

Код программы выкладываю. Это самый простой пример. Программа сама создаёт таблицу и тригер.

Использую:
OpenSUSE 12.1
PostgreSQL 8.4
Qt 4.8

На Windows всё работает отлично.


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: MetalKrot от Сентябрь 21, 2012, 15:53
Ещё одно наблюдение. Такое чувство, что сигналы становятся в очередь и не обрабатываются. Их обработка происходит если другое приложение внесло изменения в базу. И обрабатываются они все сразу. Вот лог программы.

Код:
CREATE TABLE true 
CREATE TRIGGER true
subscribeToNotification true
connect true
INSERT true
INSERT true
test
test
test

Здесь видно, что данное приложение два раза посылало запрос INSERT, а в итоге пришло три сигнала. Пришли они после того, как в другом приложении был выполнен аналогичный запрос INSERT.


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: fte от Сентябрь 21, 2012, 16:29
Код:
BEGIN
       LISTEN classif_n;  -- Зачем триггер подписываете на получение сообщений?
       NOTIFY classif_n;
       RETURN NULL; -- в таблицу ничего не добавилось, так и надо ?
END;


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: MetalKrot от Сентябрь 22, 2012, 11:09
Насчет подписания тригера. Я точно не знаю, знающий человек сказал что в документации так описано. Впринципе без этого тоже работает корректно, скорее всего нужно убрать эту строчку.

Насчет возвращаемого значения. В таблицу добавилось, тригер срабатывает после внесения изменений в таблицу.

Вопрос не в этом. Данная программа является минимальным примером.


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: MetalKrot от Сентябрь 26, 2012, 09:28
Я не могу поверить, что никто не сталкивался с данной проблемой. Была же тема уже такая. Только там так и не разобрались с данной проблемой.
Линуксоиды! Помогите!


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: Bepec от Сентябрь 26, 2012, 09:35
Нужно призывать страшных линуксоидов и использовать дебаггер :)

PS я виндузятник :)


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: MetalKrot от Сентябрь 26, 2012, 09:41
А что дебагить? Драйвера? Дебагил, работают правильно. Свой код? Дебагил, работает правильно. Куда дальше лезть? Единственный вариант остался QSocetNotify (если не ошибся с названием). Он обрабатывает сигналы. Если же и в нем будет всё нормально, тогда остаётся только база. Значит нужно искать исходники базы и колупать их, чего мне делать очень не хочется...


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: Bepec от Сентябрь 26, 2012, 09:53
Дебажить надо свой код и код Qt. Да - да, тот класс который обрабатывает получаемые сообщения.

PS хотя логика есть в таком поведении. Это же linux. Программа изменила данные. Значит программа знает что делает. А если незнает, то плохая программа. (меняем программу на пользователь и получаем философию linux)

PPS а зафига вам, извиняюсь, сообщение об изменении программе, которая их вносит?

PPPS Мб это логика БД в linux?



Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: Пантер от Сентябрь 26, 2012, 09:56
Дебажить надо свой код и код Qt. Да - да, тот класс который обрабатывает получаемые сообщения.

PS хотя логика есть в таком поведении. Это же linux. Программа изменила данные. Значит программа знает что делает. А если незнает, то плохая программа. (меняем программу на пользователь и получаем философию linux)

PPS а зафига вам, извиняюсь, сообщение об изменении программе, которая их вносит?

PPPS Мб это логика БД в linux?

Неправильно мыслишь. Части изменения и реагирования на изменения могут быть совсем не взаимосвязаны.


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: fte от Сентябрь 26, 2012, 12:22
Все-таки напишите для начала "правильную" триггерную функцию
Код:
BEGIN
       NOTIFY classif_n;
       RETURN new;
END;

PS: у меня сервер по FreeBSD, клиент под XP - все работает как надо


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: fte от Сентябрь 26, 2012, 12:30
Да кстати, при добавлении записи все-таки надо пользоваться транзакциями!

QSqlDatabase.transaction();
QSqlDatabase.commit();
QSqlDatabase.rollback();

нотифая не будет пока не закончится транзакция!

 


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: Пантер от Сентябрь 26, 2012, 12:34
QSqlQuery внутри использует транзакцию на каждый exec, на сколько я помню.


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: fte от Сентябрь 26, 2012, 13:18
Не поленился посмотрел исходники, не нашел нигде, чтобы QSqlQuery использовал QSqlDarabase.transaction()
и вообще с какого он должен использовать внутри транзакции? А если мне надо обернуть в транзакцию два инсерта в разные таблицы?


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: Пантер от Сентябрь 26, 2012, 13:30
Не поленился посмотрел исходники, не нашел нигде, чтобы QSqlQuery использовал QSqlDarabase.transaction()
и вообще с какого он должен использовать внутри транзакции? А если мне надо обернуть в транзакцию два инсерта в разные таблицы?
Или это только с SQLite было... Не помню уже. :)
А транзакция используется, если явной нет.


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: fte от Сентябрь 26, 2012, 13:55
Цитировать
Здесь видно, что данное приложение два раза посылало запрос INSERT, а в итоге пришло три сигнала. Пришли они после того, как в другом приложении был выполнен аналогичный запрос INSERT.

Вот это очень похоже, на то что висит незакрытая транзакция..... когда ее "захлопнули" пользователь получил чохом все три нотифая....


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: Odyssey от Октябрь 03, 2012, 13:41
Решаю эту же проблему.
Я изменяю таблицу запросами внутри программы.
Попробовал засунуть выполнение запроса внутрь транзакции - ничего не вышло.


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: andrew.k от Октябрь 03, 2012, 20:51
По идее нотифай в собственную сессию приходить не должен.
Это описано в документации (http://www.postgresql.org/docs/8.4/static/sql-notify.html) (последний абзац).
Поэтому не пойму, что за проблему вы решаете и зачем?

А вот откуда приходят два лишних нотифая, мне не ясно.


Название: Re: Не доходят NOTIFY от базы PostgreSQL на линуксе
Отправлено: MetalKrot от Октябрь 09, 2012, 10:01
После долгих колупаний кода мы нашли одно интересное решение. Решение найдено пальцем в небо. В итоге нужно будет пересобрать драйвейра под БД.
Открываем проект драйверов. Находим файл qsql_psql.cpp. В методе subscribeToNotificationImplementation находим создание сокета:
d->sn = new QSocketNotifier(socket, QSocketNotifier::Read);
На винде это работает отлично, а вот на линуксе - не работает. Зато если поменять второй параметр в конструкторе на QSocketNotifier::Write, то на линуксе всё работает нормально, а на винде не работает.
Мы долго пытались понять что к чему, но ответа не нашли. Да и времени свободного нету.

Теорию насчет транзакций ещё не добрался проверить, но кажется мне, что не прокатит она..