Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Перехват сообщений / 7 сообщений из 7, страница 1 из 1
11.08.2006, 10:36
    #33912368
sam21
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перехват сообщений
Добрый день!

Есть вопрос по поводу того, как можно перехватывать из Java-программы сообщения, генерируемые в процессе выполнения хранимой процедуры (raise...).

Например, есть ХП, реализующая сложный анализ данных в базе и постепенно выдающая некоторую информацию в виде сообщений. В Java-программе необходимо получать эти сообщения и по типу сообщения совершать те или иные действия.

Может кто-нибудь подскажет способ лучше.

Заранее благодарен.
...
Рейтинг: 0 / 0
11.08.2006, 10:53
    #33912424
domanix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перехват сообщений
Не совсем понял - тебе надо Raise перехватить?
и для чего не совсем понял...
Но рискну предположить что тебе надо Notify
Подробнее смотри в доке...
...
Рейтинг: 0 / 0
11.08.2006, 11:18
    #33912561
sam21
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перехват сообщений
Да, возможно. Еще проблема в том, что ХП написана на plpgsql. Очень бы не хотелось перепиывать ее на java или C.

Посмотрел про LISTEN/NOTIFY. Не понял можно ли в сообщениях передавать переменные.
...
Рейтинг: 0 / 0
11.08.2006, 12:53
    #33913002
Алексей Ключников
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перехват сообщений
В сообщениях можно передавать строку.
правда с ограничениями, кажется там обязательно должны быть буквы,
на одни цифры ругается.
Строку конечно же можно собрать из переменных.
...
Рейтинг: 0 / 0
11.08.2006, 15:42
    #33913662
sam21
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перехват сообщений
В документации по JDBC обнаружил, что JDBC driver не поддерживает асинхронные нотификации и должен постоянно опрашивать backend на их появление.

Т.е. предлагается делать следующим образом:

class Listener extends Thread {

private Connection conn;
private org.postgresql.PGConnection pgconn;

Listener(Connection conn) throws SQLException {
this.conn = conn;
this.pgconn = (org.postgresql.PGConnection)conn;
Statement stmt = conn.createStatement();
stmt.execute("LISTEN mymessage");
stmt.close();
}

public void run() {
while (true) {
try {
// issue a dummy query to contact the backend
// and receive any pending notifications.
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 1");
rs.close();
stmt.close();

org.postgresql.PGNotification notifications[] = pgconn.getNotifications();
if (notifications != null) {
for (int i=0; i<notifications.length; i++) {
System.out.println("Got notification: " + notifications .getName());
}
}

// wait a while before checking again for new
// notifications
Thread.sleep(500);
} catch (SQLException sqle) {
sqle.printStackTrace();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}

}

Не хотелось бы по таймайту постоянно обращаться к БД. К тому же в моем случае нельзя его точно выставить, а реакция на событие ДОЛЖНА происходить сразу после его возникновения.

Может есть способ лучше. Подскажите.

Заранее спасибо.
...
Рейтинг: 0 / 0
11.08.2006, 18:09
    #33914116
pasha701
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перехват сообщений
//-- raise notice можно отловить, смотри ниже
//-- даже если во время віполнения возник SQLException,
//-- notice будут сидеть в Statement
//------------------

//-- do something ---
ResultSet rs=st.executeQuery("Select * from _test_Notice(1)");
if(rs.next())
System.out.println("result="+rs.getString(1));

//-- show notices ---
SQLWarning warning=st.getWarnings();
while (warning!=null){
System.out.println(""+warning.toString());
warning=warning.getNextWarning();
}
...
Рейтинг: 0 / 0
14.08.2006, 04:28
    #33915264
фффф
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перехват сообщений
sam21В документации по JDBC обнаружил, что JDBC driver не поддерживает асинхронные нотификации и должен постоянно опрашивать backend на их появление.
...
Не хотелось бы по таймайту постоянно обращаться к БД. К тому же в моем случае нельзя его точно выставить, а реакция на событие ДОЛЖНА происходить сразу после его возникновения.

Насчёт постоянного опроса - наверное не совсем правильно дергать сервер запросами типа "select 1" (пакет туда и обратно). По идее, на клиента сообщение приходит сразу же после NOTIFY+commit, и достаточно проверить наличие данных на порту, но видимо JDBC это не поддерживает.
Кстати, это нужно иметь в виду - сообщения отправленные внутри долгой транзакции не будут отправлены до её коммита, и несколько сообщений с одинаковым текстом "слипаются" в одно.

Как вариант, можно писАть в сокет untrusted-функцией, а своей программой слушать. При этом надо будет самому держать список подписчиков, это не очень надёжно, но достаточно быстро.
Или можно использовать готовый message queue service гарантирующий доставку.

Наконец, если реакция на событие ДОЛЖНА происходить СРАЗУ - может лучше прямо выполнять этот код на сервере?
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Перехват сообщений / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]