2016-12-11 12 views
1

Я использую JOOQ в бэкэндовых веб-сервисах некоторое время. Во многих из этих сервисов, после сохранения данных в базе данных (или, лучше сказать, после успешной передачи данных), мы обычно хотим написать некоторые сообщения Кафке о сохраненных записях, чтобы другие службы знали об этих событиях.Заключительный крюк в JOOQ

Что я, по сути, ищу, есть: есть ли способ зарегистрировать привязку или обратный вызов после коммита с объектом JQQ DSLContext, поэтому я могу запустить некоторый код, когда транзакция успешно завершится?

Я знаю интерфейсов ExecuteListener и ExecuteListenerProvider, но, насколько я могу сказать void end(ExecuteContext ctx) метод (который, предположительно, для завершения жизненного цикла используется) не вызывается при совершении сделки. Он вызывается после каждого запроса.

Вот пример:

public static void main(String[] args) throws Throwable { 
    Class.forName("org.postgresql.Driver"); 
    Connection connection = DriverManager.getConnection("<url>", "<user>", "<pass>"); 
    connection.setAutoCommit(false); 

    DSLContext context = DSL.using(connection, SQLDialect.POSTGRES_9_5); 
    context.transaction(conf -> { 
     conf.set(new DefaultExecuteListenerProvider(new DefaultExecuteListener() { 
      @Override 
      public void end(ExecuteContext ctx) { 
       System.out.println("End method triggered."); 
      } 
     })); 

     DSLContext innerContext = DSL.using(conf); 
     System.out.println("Pre insert."); 
     innerContext.insertInto(...).execute(); 
     System.out.println("Post insert."); 
    }); 

    connection.close(); 
} 

Который всегда кажется печати:

Pre insert. 
End method triggered. 
Post insert. 

Делать мне поверить, что это не предназначено для фиксации крючков.

Возможно, есть гуру JOOQ, который может сказать мне, есть ли поддержка для фиксации крюков в JOOQ? И если так, укажите меня в правильном направлении?

+1

Попробуйте комбинировать 'TransactionProvider',' RecordListener' и 'ExecuteListener'. Вы могли бы записывать записи c/u/d в поток локально и либо отбрасывать, либо публиковать в зависимости от завершения самой внешней транзакции. –

ответ

1

ExecuteListener SPI прослушивает жизненный цикл выполнения одного запроса выполняется, то есть это:

innerContext.insertInto(...).execute(); 

Это не то, что вы ищете. Вместо этого вы должны реализовать свой собственный TransactionProvider (возможно, делегируя jQQ DefaultTransactionProvider). Затем вы можете реализовать любую логику, которая вам нужна, до фактической логики фиксации.

Обратите внимание, что jOOQ 3.9 также предоставит новый TransactionListener SPI (see #5378), чтобы облегчить это.

+0

Может быть немного беспорядочно получить «TransactionProvider» из «DSLContext», бросить его, а затем прикрепить обратный вызов, но мне удалось заставить его работать правильно. Большое спасибо Лукасу! Btw, с нетерпением жду нового «TransactionListener» в 3,9, но я заметил, что вы можете устанавливать только слушателей. Почему бы не добавить их во время выполнения? –

+0

@MichaeldeJong Да, это решение обратного вызова будет работать хорошо. Почему, по вашему мнению, вы не сможете добавить слушателей во время выполнения? –

+0

Возможно, я ошибаюсь (возможно), но смотрю на [код] (https://github.com/jOOQ/jOOQ/commit/4e1f458e6c1f0e1e7e695f84890956fb8cc30ecd#diff-5b0bc82019c25f8bf90f60d2b2177b17R806), каждый раз, когда вы вызываете этот метод, он заменяет все был ранее установлен. Я знаю, что это «TransactionListenerProvider», а не «TransactionListener», но если вы хотите добавить/зарегистрировать его во время транзакции, вам нужно будет сначала выбрать все поставщики, добавить новый в измененный массив и вызовите метод 'set (TransactionListenerProvider ...)' правильно? –

 Смежные вопросы

  • Нет связанных вопросов^_^