#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);