Database Change Notification

116
03 марта 2021, 23:30

Разбираюсь с механизмом нотификаций в оракле. Возникло два вопроса

  1. Вот здесь приводят такой код регистрации обработчика событий

    DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotification(prop);
    .......
    // second step: add objects in the registration:
    Statement stmt = conn.createStatement();
    // associate the statement with the registration:
    ((OracleStatement)stmt).setDatabaseChangeRegistration(dcr);
    ResultSet rs = stmt.executeQuery("select * from dept where deptno='45'");
    while (rs.next())
    {}
    rs.close();
    stmt.close();
    

    Вопрос по этому куску

    ResultSet rs = stmt.executeQuery("select * from dept where deptno='45'");
    while (rs.next()) {}
    
    1. Если я хочу отловить событие вставки новой записи, то я должен писать так

      ResultSet rs = stmt.executeQuery("select * from dept");
      while (rs.next()) {}
      

      а если у меня в таблице миллион записей, то получается, что я должен весь этот миллион зафетчить на клиента?

    2. И еще, а проверил, отлично работает и такой код

      stmt.execute("select * from dept");
      

      я подложил себе такой модификацией какие-то грабли?

  2. Вопрос номер два. Вот здесь звучит фраза

    По умолчанию регистрации создаются без таймаута. То есть, как бы, навечно. Как правило, такая регистрация никому не нужна, ведь время работы приложения обычно ограничено. Такую регистрацию очень сложно потом выковырять из базы, тем более, если их будет много. Правильным путем, по всей видимости, было бы удаление регистрации при завершении работы с ней ... Однако, как мне кажется, этот метод подходит только для идеальных миров, в которых ваши приложения никогда не падают, каналы связи никогда не рвутся и ресурсы всегда освобождаются. В противном случае, в конечном счете, мы будем иметь то же самое, что и без удаления, правда, последствия начнут проявляться позже....

    Мы решили проблему таким образом – стали всегда указывать таймаут при регистрации. И за несколько секунд до его истечения удалять старую регистрацию и создавать новую.

    Я тоже пошел по этому пути, но может есть штатный способ?

    Придуманная мной альтернатива, это сохранять в базе regid, а потом, по старту программы, вычищать старые регистрации таким кодом

    Statement stmt= conn.createStatement();
    ResultSet rs = stmt.executeQuery(
      "select regid,callback from USER_CHANGE_NOTIFICATION_REGS WHERE regid IN (......)"
    );
    while(rs.next())
    {
      long regid = rs.getLong(1);
      String callback = rs.getString(2);
      ((OracleConnection)conn).unregisterDatabaseChangeNotification(regid,callback);
    }
    rs.close();
    stmt.close();
    

    но у такого способа я вижу два недостатка

    1. Пока программа не запущена, подписка висит на сервере
    2. После перезапуска сервера Оракла последовательность regid не будет сброшена? И не отменю ли я так чужую подписку?
READ ALSO
Почему приведение типов к базовому не заставляет выполнять метод базового типа?

Почему приведение типов к базовому не заставляет выполнять метод базового типа?

Учусь программироватьУ меня есть классы (Базовый и производный)

96
видимость значения при синхронизированном изменении

видимость значения при синхронизированном изменении

Насколько известно, изменив volatile переменную, мы остаёмся уверенны, что остальные потоки, которые будут её читать, получат новое значениеПричина...

101
Почему при записи файла файл пустой?

Почему при записи файла файл пустой?

файл сохраняется но он пустойпри дебаге выяснилось что output пустой

119
Почему не работает click()?

Почему не работает click()?

Всё хорошо работает до выполнения click()Выдаёт исключение: org

94