Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> listener изменений БД 
V
    Опции темы
Temdegon
Дата 10.9.2009, 03:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 11.10.2008
Где: Minsk

Репутация: 7
Всего: 9



Есть таблица БД. В нее время от времени кто-то что-то пишет, апдейтит, делитит.
Есть приложение, которое должно реагировать на изменения этой таблицы. Ну, для примера, отображать в реальном времени данные из таблицы в JTable. Можно ли как-то "научить" БД сообщать клиенту о событиях? Как бы триггер, но что бы он вызывал какой-то метод.
Очень не хочется реализовывать это самому, через постоянное перечитывание таблицы.
В БД H2 есть поддержка Java-триггеров, но я не совсем понял, то ли это, что мне нужно. Как я понимаю, Java-триггер для H2 это как бы аналог триггеров в других БД, только в качестве языка используется не какой-нить PL/pgSQL, а Java.
Решение хотелось бы не привязанное к конкретной БД.
PM MAIL   Вверх
AlexeyVorotnikov
Дата 10.9.2009, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 18.6.2007
Где: Москва

Репутация: 10
Всего: 18



Цитата(Temdegon @  10.9.2009,  04:19 Найти цитируемый пост)
Решение хотелось бы не привязанное к конкретной БД

Вот это сильно вряд ли. Поскольку на изменение в таблице должна реагировать именно БД. И не во всякой БД есть такая воможность.



--------------------
RTFM!
Три источника и три составные части Java: The Java Language Specification, Java Platform API Specification, The Java Virtual Machine Specification
PM MAIL   Вверх
Temdegon
Дата 10.9.2009, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 11.10.2008
Где: Minsk

Репутация: 7
Всего: 9



почитал доки по PostgreSQL, вроде как там есть механизм установки листнера из си, и если сильно затотеть, то можно как-нить прикрутить его к Java. 
Но хотелось бы найти какое-то готовое решение для Java. Вроде как задача не такая уж уникальная.
PM MAIL   Вверх
jeank
Дата 10.9.2009, 12:20 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 26.6.2008
Где: Калининград

Репутация: нет
Всего: 1



А Вам просто не хватает трехзвенной архитектуры с сервером приложений посередине, на который и вешаются такого рода и не только задачи (слушатели, транзакции, блокировки и т.д.).
PM MAIL WWW   Вверх
Temdegon
Дата 25.9.2009, 04:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 11.10.2008
Где: Minsk

Репутация: 7
Всего: 9



Собственно, вот чего мне не хватало:

postgresql-jdbc-8.3 
Цитата

Listen / Notify

Listen and Notify provide a simple form of signal or interprocess communication mechanism for a collection of processes accessing the same PostgreSQL™ database. For more information on notifications consult the main server documentation. This section only deals with the JDBC specific aspects of notifications.

Standard LISTEN, NOTIFY, and UNLISTEN commands are issued via the standard Statement interface. To retrieve and process retrieved notifications the Connection must be cast to the PostgreSQL™ specific extension interface PGConnection. From there the getNotifications() method can be used to retrieve any outstanding notifications.
Note

A key limitation of the JDBC driver is that it cannot receive asynchronous notifications and must poll the backend to check if any notifications were issued. 


Код

import java.sql.*;

public class NotificationTest {

    public static void main(String args[]) throws Exception {
        Class.forName("org.postgresql.Driver");
        String url = "jdbc:postgresql://localhost:5432/test";

        // Create two distinct connections, one for the notifier
        // and another for the listener to show the communication
        // works across connections although this example would
        // work fine with just one connection.
        Connection lConn = DriverManager.getConnection(url,"test","");
        Connection nConn = DriverManager.getConnection(url,"test","");

        // Create two threads, one to issue notifications and
        // the other to receive them.
        Listener listener = new Listener(lConn);
        Notifier notifier = new Notifier(nConn);
        listener.start();
        notifier.start();
    }

}

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[i].getName());
                    }
                }

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

}

class Notifier extends Thread {

    private Connection conn;

    public Notifier(Connection conn) {
        this.conn = conn;
    }

    public void run() {
        while (true) {
            try {
                Statement stmt = conn.createStatement();
                stmt.execute("NOTIFY mymessage");
                stmt.close();
                Thread.sleep(2000);
            } catch (SQLException sqle) {
                sqle.printStackTrace();
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }

}


Что бы Listner получил notification, кто-то должен выполнить "NOTIFY". Можно в клиента добавить код, посылающий notify после именения данных, а можно просто повесить триггер на update\delete\insert и пусть он посылает уведомление. 

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0669 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.