Is there a way to correlate jOOQ transaction & record listeners?
I need to trigger certain actions once records where added to a certain table. RecordListener#insertEnd
is the proper hook for that but to my knowledge this does not guarantee that the records were really inserted. The transaction may still rollback after insertEnd()
was called - or the insert to one table may be part of a batch of inserts that also affects other tables.
If, on the other hand, I implement TransactionListener#comitEnd
I can't figure out which records where actually inserted. TransactionContext
doesn't have this information.
You can do this by accessing the Configuration.data()
property, which has been created for this purpose. Consider these two listeners:
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");
}
}
This could then be used as follows:
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);