Сопоставление прослушивателей транзакций и записей jOOQ

#java #sql #jooq

#java #sql #jooq

Вопрос:

Есть ли способ сопоставить прослушиватели транзакций и записей jOOQ?

Мне нужно запускать определенные действия после добавления записей в определенную таблицу. RecordListener#insertEnd это правильный хук для этого, но, насколько мне известно, это не гарантирует, что записи действительно были вставлены. Транзакция может по-прежнему откатываться после insertEnd() вызова — или вставка в одну таблицу может быть частью пакета вставок, который также влияет на другие таблицы.

Если, с другой стороны, я реализую TransactionListener#comitEnd , я не могу понять, какие записи на самом деле вставлены. TransactionContext у него нет этой информации.

Ответ №1:

Вы можете сделать это, обратившись к Configuration.data() свойству, которое было создано для этой цели. Рассмотрим эти два прослушивателя:

 class RL extends DefaultRecordListener {
    @Override
    public void insertEnd(RecordContext ctx) {
        // Put some property into the data map
        ctx.configuration().data("x", "y");
    }
}

class TL extends DefaultTransactionListener {
    String x;

    @Override
    public void commitEnd(TransactionContext ctx) {
        // Retrieve the property again
        x = (String) ctx.configuration().data("x");
    }
}
 

Затем это можно было бы использовать следующим образом:

 RL rl = new RL();
TL tl = new TL();

ctx.configuration()
   .derive(rl)
   .derive(tl)
   .dsl()
   .transaction(c -> {
        assertNull(c.data("x"));

        TRecord t = c.dsl().newRecord(T);
        t.setA("a");
        t.setB("b");

        // insertEnd() triggered here
        assertEquals(1, t.insert());
        assertEquals("y", c.data("x"));

    // commitEnd() triggered here
    });

// Since the transaction creates a nested, derived scope, you don't see these things
// from the outside of the transaction in your possibly global Configuration
assertNull(ctx.data("x"));
assertNull(ctx.configuration().data("x"));
assertEquals("y", tl.x);